home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / iso9660 / security / logtcp51.shr / text0000.txt < prev   
Encoding:
Text File  |  1993-03-24  |  146.6 KB  |  4,282 lines

  1. The new wrapper release causes occasional kernel panics with SunOS 4.x.
  2. There is a bug in the getsockopt() system call implementation.
  3.  
  4. Getsockopt() was used to detect source-routing attacks. That code was
  5. enabled by default. I have changed this: by default the code no longer
  6. tries to expose source-routing attacks.
  7.  
  8. The result of this effort is below. Changes were made only to the
  9. documentation, to the Makefile, and to the patchlevel.h file.
  10.  
  11. Please replace the wrapper archives on cert.org. I will post a separate
  12. message to the cert-tools mailing list.
  13.  
  14.     Wietse
  15. --------------
  16.  
  17. With the programs that come with this kit you can monitor incoming
  18. requests for IP services such as TFTP, EXEC, FTP, RSH, TELNET, RLOGIN,
  19. FINGER, SYSTAT, and many others.
  20.  
  21. Optional features are: access control based on pattern matching; remote
  22. username lookup using the RFC 931 protocol; protection against attacks
  23. from hosts that pretend to have someone elses name; protection against
  24. attacks from hosts that pretend to have someone elses network address.
  25.  
  26. The programs can be installed without requiring any changes to existing
  27. software or configuration files. By default, they just log the remote
  28. host name and do some sanity checks on the origin the request. No
  29. information is exchanged with the remote client process.
  30.  
  31. The most notable differences with respect to the previous release are:
  32.  
  33.     - Optional protection against attacks from hosts that pretend to
  34.     have someone elses network address. For example, the address of a
  35.     trusted host within your own network.
  36.  
  37.     - The access control language has been extended with a simple but
  38.     powerful operator that greatly simplifies the design of rule sets
  39.     (ALL: .foo.edu EXCEPT dialup.foo.edu). Blank lines are permitted,
  40.     and long lines can be continued with backslash-newline.
  41.  
  42.     - All configurable stuff, including path names, has been moved into
  43.     the Makefile so that you no longer have to hack source code to just
  44.     configure the programs.
  45.  
  46.     - Ported to Solaris 2. TLI-based applications not yet supported.
  47.     Several workarounds for System V bugs.
  48.  
  49.     - A small loophole in the netgroup lookup code was closed, and the
  50.     remote username lookup code was made more portable.
  51.  
  52.     - Still more documentation. The README file now provides tutorial
  53.     sections with introductions to client, server, inetd and syslogd.
  54.  
  55. The default mode of operation should be backwards compatible with
  56. earlier versions.
  57.  
  58.     Wietse Venema (wietse@wzv.win.tue.nl),
  59.     Department of Mathematics and Computing Science,
  60.     Eindhoven University of Technology,
  61.     The Netherlands.
  62.  
  63.  
  64. #! /bin/sh
  65. # This is a shell archive.  Remove anything before this line, then unpack
  66. # it by saving it into a file and typing "sh file".  To overwrite existing
  67. # files, type "sh file -c".  You can also feed this as standard input via
  68. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  69. # will see the following message at the end:
  70. #        "End of shell archive."
  71. # Contents:  README miscd.c tcpd.c fromhost.c hosts_access.c
  72. #   shell_cmd.c log_tcp.h try.c refuse.c Makefile.dist hosts_access.5
  73. #   strcasecmp.c BLURB rfc931.c tcpd.8 hosts_info.c hosts_access.3
  74. #   hosts_ctl.c percent_x.c options.c clean_exit.c setenv.c
  75. #   patchlevel.h strtok.c fix_options.c inet_addr_fix
  76. # Wrapped by wietse@wzv on Wed Mar 24 22:44:58 1993
  77. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  78. if test -f README -a "${1}" != "-c" ; then 
  79.   echo shar: Will not over-write existing file \"README\"
  80. else
  81. echo shar: Extracting \"README\" \(34888 characters\)
  82. sed "s/^X//" >README <<'END_OF_README'
  83. X@(#) README 1.10 93/03/24 22:42:46
  84. X
  85. X
  86. XTable of contents
  87. X-----------------
  88. X
  89. X    1 - Introduction
  90. X    2 - Disclaimer
  91. X    3 - Tutorials
  92. X        3.1 - How it works
  93. X        3.2 - Where the logging information goes
  94. X    4 - Features
  95. X        4.1 - Access control
  96. X        4.2 - Host name spoofing
  97. X        4.3 - Host address spoofing
  98. X        4.4 - Remote username lookups
  99. X        4.5 - Language extension hooks
  100. X    5 - Other works
  101. X        5.1 - Related documents
  102. X        5.2 - Related software
  103. X    6 - Limitations
  104. X        6.1 - Known wrapper limitations
  105. X        6.2 - Known system software bugs
  106. X    7 - Configuration and installation
  107. X        7.1 - Easy configuration and installation
  108. X        7.2 - Advanced configuration and installation
  109. X        7.3 - Daemons with arbitrary path names
  110. X        7.4 - Building and testing the access control rules
  111. X        7.5 - Other applications
  112. X    8 - Acknowledgements
  113. X
  114. X1 - Introduction
  115. X----------------
  116. X
  117. XWith this package you can monitor incoming connections to the SYSTAT,
  118. XFINGER, FTP, TELNET, RLOGIN, RSH, EXEC, TFTP, TALK, and other network
  119. Xservices.  
  120. X
  121. XThe package provides tiny daemon wrapper programs that can be installed
  122. Xwithout any changes to existing software or to existing configuration
  123. Xfiles.  The wrappers report the name of the remote host and of the
  124. Xrequested service; the wrappers do not exchange information with the
  125. Xremote client process, and impose no overhead on the actual
  126. Xcommunication between the client and server applications.
  127. X
  128. XOptional features are: access control to restrict what systems can
  129. Xconnect to your network daemons; remote user name lookups with the RFC
  130. X931 protocol; additional protection against hosts that pretend to have
  131. Xsomeone elses host name; additional protection against hosts that
  132. Xpretend to have someone elses host address.
  133. X
  134. XEarly versions of the programs were tested with Ultrix >= 2.2, with
  135. XSunOS >= 3.4 and ISC 2.2. Later versions have been installed on a wide
  136. Xvariety of platforms such as SunOS 4.x and 5.x, Ultrix 3.x and 4.x, DEC
  137. XOSF/1 T1.2-2, HP-UX 8.x, AIX 3.1.5, Apollo SR10.3.5, Sony, NeXT, SCO
  138. XUNIX, DG/UX, Cray, and an unknown number of other ones.  
  139. X
  140. XRequirements are that the network daemons are spawned by a super server
  141. Xsuch as the inetd; a 4.3BSD-style socket programming interface; and the
  142. Xavailability of a syslog(3) library and of a syslogd(8) daemon.  The
  143. Xwrappers should run without modification on any system that satisfies
  144. Xthese requirements.  Workarounds have been implemented for several
  145. Xcommon bugs in systems software.
  146. X
  147. XWhat to do if this is your first encounter with the wrapper programs:
  148. X1) read the tutorial sections for an introduction to the relevant
  149. Xconcepts and terminology; 2) glance over the security feature sections
  150. Xin this document; 3) follow the installation instructions (easy or
  151. Xadvanced). I recommend that you first use the default security feature
  152. Xsettings.  Run the wrappers for a few days to become familiar with
  153. Xtheir logs, before doing anything drastic such as cutting off access or
  154. Xinstalling booby traps.
  155. X
  156. X2 - Disclaimer
  157. X--------------
  158. X
  159. XThe wrapper programs rely on source address information obtained from
  160. Xnetwork packets. Such information is not 100 percent reliable, although
  161. Xthe wrappers do their best to expose forgeries.
  162. X
  163. XIn the absence of cryptographic protection of message contents, and of
  164. Xcryptographic authentication of message originators, all data from the
  165. Xnetwork should be treated with sound scepticism.
  166. X
  167. XTHIS RESTRICTION IS BY NO MEANS SPECIFIC TO THE TCP/IP PROTOCOLS.
  168. X
  169. X3 - Tutorials
  170. X-------------
  171. X
  172. XThe tutorial sections give a gentle introduction to the operation of
  173. Xthe wrapper programs, and introduce some of the terminology that is
  174. Xused in the remainder of the document: client, server, the inetd and
  175. Xsyslogd daemons, and their configuration files.
  176. X
  177. X3.1 - How it works
  178. X------------------
  179. X
  180. XAlmost every application of the TCP/IP protocols is based on a client-
  181. Xserver model. For example, when a user invokes the telnet command to
  182. Xconnect to one of your systems, a telnet server process is executed on
  183. Xthe target host. The telnet server process connects the user to a login
  184. Xprocess. A few examples of client and server programs are shown in the
  185. Xtable below:
  186. X
  187. X              client   server    application
  188. X              --------------------------------
  189. X              telnet   telnetd   remote login
  190. X              ftp      ftpd      file transfer
  191. X              finger   fingerd   show users
  192. X
  193. XThe usual approach is to run one single daemon process that waits for
  194. Xall kinds of incoming network connections. Whenever a connection is
  195. Xestablished, this daemon (usually called inetd) runs the appropriate
  196. Xserver program and goes back to sleep, waiting for other connections.
  197. X
  198. XThe wrapper programs rely on a simple, but powerful mechanism.  Instead
  199. Xof directly running the desired server program, the inetd is tricked
  200. Xinto running a small wrapper program. The wrapper logs the remote host
  201. Xname or address and performs some additional checks.  When all is well,
  202. Xthe wrapper executes the desired server program and goes away.
  203. X
  204. XThe wrapper programs have no interaction with the remote user (or
  205. Xclient process).  This has two major advantages: 1) the wrappers are
  206. Xapplication-independent, so that the same program can protect many
  207. Xkinds of network services; 2) no interaction also means that the
  208. Xwrappers are invisible from outside (at least for regular users).
  209. X
  210. XAnother important property is that the wrapper programs are active only
  211. Xwhen the initial contact between client and server is established. Once
  212. Xa wrapper has done its work there is no overhead on the client-server
  213. Xcommunication.
  214. X
  215. XThe simple mechanism has one major drawback: since the wrappers go away
  216. Xafter the initial contact between client and server processes, the
  217. Xwrappers are of little use with network daemons that service more than
  218. Xone client.  The wrappers would only see the first client attempt to
  219. Xcontact such a server. The NFS mount daemon is a typical example of
  220. Xa daemon that services requests from multiple clients.
  221. X
  222. XThere are two ways to use the wrapper programs:
  223. X
  224. X1) The easy way: move network daemons to some other directory and fill
  225. X   the resulting holes with copies of the wrapper programs.  This
  226. X   approach involves no changes to configuration files, so there is
  227. X   very little risk of breaking things.
  228. X
  229. X2) The advanced way: leave the network daemons alone and modify the
  230. X   inetd configuration file.  For example, an entry such as:
  231. X
  232. X     tftp  dgram  udp  wait  root  /usr/etc/tcpd  in.tftpd -s /tftpboot
  233. X
  234. X   When a tftp request arrives, inetd will run the wrapper program
  235. X   (tcpd) with a process name `in.tftpd'.  This is the name that the
  236. X   wrapper will use when logging the request and when scanning the
  237. X   optional access control tables.  `in.tftpd' is also the name of the
  238. X   server program that the wrapper will attempt to run when all is
  239. X   well.  Any arguments (`-s /tftpboot' in this particular example) are
  240. X   transparently passed on to the server program.
  241. X
  242. XFor an account of the history of the wrapper programs, with real-life
  243. Xexamples, see the section below on related documents.
  244. X
  245. X3.2 - Where the logging information goes
  246. X----------------------------------------
  247. X
  248. XThe wrapper programs send their logging information to the syslog
  249. Xdaemon (syslogd). The disposition of the wrapper logs is determined by
  250. Xthe syslog configuration file (usually /etc/syslog.conf). Messages are
  251. Xwritten to files, to the console, or are forwarded to a @loghost.
  252. X
  253. XOlder syslog implementations (still found on Ultrix systems) only
  254. Xsupport priority levels ranging from 9 (debug-level messages) to 0
  255. X(alerts). All logging information of the same priority level (or more
  256. Xurgent) is written to the same destination.  In the syslog.conf file,
  257. Xpriority levels are specified in numerical form.  For example,
  258. X
  259. X    8/usr/spool/mqueue/syslog
  260. X
  261. Xcauses all messages with priority 8 (informational messages), and
  262. Xanything that is more urgent, to be appended to the file
  263. X/usr/spool/mqueue/syslog.
  264. X
  265. XNewer syslog implementations support message classes in addition to
  266. Xpriority levels.  Examples of message classes are: mail, daemon, auth
  267. Xand news. In the syslog.conf file, priority levels are specified with
  268. Xsymbolic names: debug, info, notice, ..., emerg. For example,
  269. X
  270. X    mail.debug            /var/log/syslog
  271. X
  272. Xcauses all messages of class mail with priority debug (or more urgent)
  273. Xto be appended to the /var/log/syslog file.
  274. X
  275. XBy default, the wrapper logs go to the same place as the transaction
  276. Xlogs of the sendmail daemon. The disposition can be changed by editing
  277. Xthe Makefile and/or the syslog.conf file. Send a `kill -HUP' to the
  278. Xsyslogd after changing its configuration file. Remember that syslogd,
  279. Xjust like sendmail, insists on one or more TABs between the left-hand
  280. Xside and the right-hand side expressions in its configuration file.
  281. X
  282. X4 - Features
  283. X------------
  284. X
  285. X4.1 - Access control
  286. X--------------------
  287. X
  288. XWhen compiled with -DHOSTS_ACCESS, the wrapper programs support a
  289. Xsimple form of access control.  Access can be controlled per host, per
  290. Xservice, or combinations thereof. The software provides hooks for the
  291. Xexecution of shell commands when an access control rule fires; this
  292. Xfeature may be used to install "booby traps".  For details, see the
  293. Xhosts_access.5 manual page, which is in `nroff -man' format. A later
  294. Xsection describes how you can test your access control rules.
  295. X
  296. XAccess control is enabled by default. It can be turned off by editing
  297. Xthe Makefile, or by providing no access control tables. The install
  298. Xinstructions below describe the Makefile editing process.
  299. X
  300. X4.2 - Host name spoofing
  301. X------------------------
  302. X
  303. XWith some network applications, such as RSH or RLOGIN, the remote host
  304. Xname plays an important role in the authentication process. Host name
  305. Xinformation can be reliable when lookups are done from a _local_ hosts
  306. Xtable, provided that the client IP address can be trusted.
  307. X
  308. XWith _distributed_ name services, authentication schemes that rely on
  309. Xhost names become more problematic. The security of your system now may
  310. Xdepend on some far-away DNS (domain name server) outside your own
  311. Xcontrol. Paradoxically, running NIS (YP) can actually improve hostname
  312. Xsecurity because it provides you with the equivalent of a local hosts
  313. Xfile.
  314. X
  315. XThe wrapper programs verify the remote host name that is returned by
  316. Xthe address->name DNS server, by asking for a second opinion.  To this
  317. Xend, the programs look at the name and addresses that are returned by
  318. Xthe name->address DNS server. If any discrepancies are found, the
  319. Xwrappers conclude that at least one of the two name servers is lying,
  320. Xand assume that they are dealing with a host that pretends to have
  321. Xsomeone elses host name.
  322. X
  323. XWhen the wrappers are unable to verify the remote host name (the
  324. Xaddress->name lookup succeeds but the name->address lookup fails), they
  325. Xalso assume that the host name is wrong. 
  326. X
  327. XWhen the remote host name is unavailable (the address->name lookup
  328. Xfails) the wrappers just use the remote host address when logging the
  329. Xconnection and when consulting the optional access control tables.
  330. X
  331. XWhen the sources are compiled with -DPARANOID, the wrappers will drop
  332. Xthe connection in case of a host name/address mismatch. When the
  333. Xsources are not compiled with -DPARANOID, the wrappers just pretend
  334. Xthat the host name is unknown when logging the connection and when
  335. Xconsulting the optional access control tables.
  336. X
  337. XParanoid mode is enabled by default. It can be turned off by editing
  338. Xthe Makefile. The configuration and installation below describes the
  339. XMakefile editing process.
  340. X
  341. X4.3 - Host address spoofing
  342. X---------------------------
  343. X
  344. XWhile host name spoofing can be found out by asking a second opinion,
  345. Xit is much harder to find out that a host claims to have someone elses
  346. Xnetwork address. And since host names are deduced from network
  347. Xaddresses, address spoofing is at least as effective as name spoofing.
  348. X
  349. XThe wrapper programs can give additional protection against hosts that
  350. Xclaim to have an address that lies outside their own network.  For
  351. Xexample, some far-away host that claims to be a trusted host within
  352. Xyour own network. Such things are possible even while the impersonated
  353. Xsystem is up and running.
  354. X
  355. XThis additional protection is not an invention of my own; it has been
  356. Xpresent for at least five years in the BSD rsh and rlogin daemons.
  357. XUnfortunately, that feature was added *after* 4.3 BSD came out, so that
  358. Xvery few, if any, UNIX vendors have adopted it.  Our site, and many
  359. Xother ones, has been running these enhanced daemons for several years,
  360. Xand without any ill effects.
  361. X
  362. XWhen the programs are compiled with -DKILL_IP_OPTIONS, source routing
  363. Xwill be disabled for all TCP connections that are handled by the
  364. Xwrapper programs.
  365. X
  366. XAll this cannot be used with SunOS 4.x because of a kernel bug in the
  367. Ximplementation of the getsockopt() system call. Kernel panics have been
  368. Xreported for SunOS 4.1.1 and SunOS 4.1.2. The symptoms are "BAD TRAP"
  369. Xand "Data fault" while executing the tcp_ctloutput() kernel function.
  370. X
  371. XThe feature is disabled by default. It can be turned on by editing the
  372. XMakefile.  The configuration and installation section below describes
  373. Xthe Makefile editing process.
  374. X
  375. XUDP services do not benefit from this additional protection. With UDP,
  376. Xall you can be certain of is the network packet's destination address.
  377. X
  378. X4.4 - Remote username lookups
  379. X-----------------------------
  380. X
  381. XThe protocol proposed in RFC 931 provides a means to get the remote
  382. Xuser name from the client host.  The requirement is that the client
  383. Xhost runs an RFC 931-compliant daemon. The information provided by such
  384. Xa daemon is not intended to be used for authentication purposes, but it
  385. Xcan provide additional information about the owner of a TCP connection.
  386. X
  387. XRemote user name lookups are enabled when the wrappers are compiled
  388. Xwith -DRFC931.  There are some limitations: the number of hosts that
  389. Xrun an RFC 931 (or compatible) daemon is small (but growing); remote
  390. Xuser name lookups do not work for datagram (UDP) connections. More
  391. Xseriously, remote user name lookups can cause noticeable delays with
  392. Xconnections from non-UNIX PCs. The wrappers use a 30-second timeout for
  393. XRFC931 lookups, to accommodate slow networks and slow hosts. 
  394. X
  395. XBy default, remote username lookups are not enabled. You can enable
  396. Xthem by editing the Makefile. The remote username lookup timeout period
  397. X(30 seconds default) can also be changed by editing the Makefile. The
  398. Xinstallation sections below describe the Makefile editing process.
  399. X
  400. XThe RFC 931 protocol has diverged into different directions (IDENT and
  401. XTAP). To add to the confusion, both protocols use the same network
  402. Xport.  The daemon wrappers implement a common subset of the protocols.
  403. X
  404. X4.5 - Language extension hooks
  405. X------------------------------
  406. X
  407. XThe wrappers sport only a limited number of features. This is for a
  408. Xgood reason: programs that are run at high privilege levels must be
  409. Xeasy to verify.
  410. X
  411. XHowever, some sites have very specific needs.  The options.c file
  412. Xprovides a framework for adding extensions to the access control
  413. Xlanguage. It comes with sample extensions that:  (1) switch to another
  414. Xuser or group id; (2) perform remote user name lookups; (3) run an
  415. Xalternate server program (this allows you to produce customized bounce
  416. Xmessages or to do really nasty stuff); (4) set arbitrary environment
  417. Xvariables; (5) change the default file protection mask.
  418. X
  419. XThe language extension hook is not enabled by default because it
  420. Xintroduces an incompatible change to the access control language
  421. Xsyntax. Instructions to enable the extensions are given in the
  422. XMakefile.
  423. X
  424. X5 - Other works
  425. X---------------
  426. X
  427. X5.1 - Related documents
  428. X-----------------------
  429. X
  430. XThe war story behind the wrapper tools is described in:
  431. X
  432. X    W.Z. Venema, "TCP WRAPPER, network monitoring, access control and
  433. X    booby traps", UNIX Security Symposium III Proceedings (Baltimore),
  434. X    September 1992. 
  435. X
  436. X    ftp.win.tue.nl:/pub/security/tcp_wrapper.ps.Z (postscript)
  437. X    ftp.win.tue.nl:/pub/security/tcp_wrapper.txt.Z (flat text)
  438. X
  439. XThe same cracker is also described in:
  440. X
  441. X    W.R. Cheswick, "An Evening with Berferd, In Which a Cracker is
  442. X    Lured, Endured, and Studied", Proceedings of the Winter USENIX
  443. X    Conference (San Francisco), January 1992.
  444. X
  445. X    research.att.com:/dist/internet_security/berferd.ps
  446. X
  447. X5.2 - Related software
  448. X----------------------
  449. X
  450. XNetwork daemons etc. with enhanced logging capabilities can generate
  451. Xmassive amounts of information: our 100+ workstations generate several
  452. Xhundred kbytes each day. egrep-based filters can help to suppress some
  453. Xof the noise.  A more powerful tool is the Swatch monitoring system by
  454. XStephen E. Hansen and E. Todd Atkins. Swatch can process log files in
  455. Xreal time and can associate arbitrary actions with patterns; its
  456. Xapplications are by no means restricted to security.  Swatch is
  457. Xavailable from sierra.stanford.edu, directory /pub/sources.
  458. X
  459. XSocks, described in the UNIX Security III proceedings, can be used to
  460. Xcontrol network traffic from hosts on an internal network, through a
  461. Xfirewall host, to the outer world. Socks consists of a daemon that is
  462. Xrun on the firewall host, and of a library with routines that redirect
  463. Xapplication socket calls through the firewall daemon.  Socks is
  464. Xavailable from s1.gov in /pub/socks.tar.Z.
  465. X
  466. XVersions of rshd and rlogind, modified to report the remote user name
  467. Xin addition to the remote host name, are available for anonymous ftp
  468. X(ftp.win.tue.nl:/pub/security/logdaemon-2.tar.Z).  These programs are
  469. Xdrop-in replacements for SunOS 4.x, Ultrix 4.x, and SunOS 5.x.
  470. X
  471. XThe securelib shared library by William LeFebvre can be used to control
  472. Xaccess to network daemons that are not run under control of the inetd,
  473. Xsuch as the RPC daemons that run until the machine goes down.
  474. XAvailable from eecs.nwu.edu, file /pub/securelib.tar.
  475. X
  476. XWhere shared libraries or router-based packet filtering are not an
  477. Xoption, an alternative portmap daemon can help to improve RPC security,
  478. Xin particular that of NFS and of the NIS (YP) information service.
  479. Xftp.win.tue.nl:/pub/security/portmap.shar.Z was tested with SunOS 4.1.1
  480. Xand 4.1.2, Ultrix 3.0 and Ultrix 4.x, HP-UX 8.x and AIX. The protection
  481. Xis less effective than that of the securelib library because portmap is
  482. Xmostly a dictionary service.  SunOS 4.x users should install the latest
  483. Xrevision of the portmap and NIS daemons instead, or adopt NIS+ which
  484. Xhas access control built in.
  485. X
  486. XSource for a portable RFC 931 (TAP, IDENT)-compatible daemon by Peter
  487. XEriksson is available from ftp.lysator.liu.se:/pub/ident/servers.
  488. X
  489. XSome TCP/IP implementations come without syslog library. Some come with
  490. Xthe library but have no syslog daemon. A replacement can be found in
  491. Xftp.win.tue.nl:/pub/security/surrogate-syslog.tar.Z.  The fakesyslog
  492. Xlibrary that comes with the nntp sources reportedly works well, too.
  493. X
  494. X6 - Limitations
  495. X---------------
  496. X
  497. X6.1 - Known wrapper limitations
  498. X-------------------------------
  499. X
  500. XSome UDP (and RPC) daemons linger around for a while after they have
  501. Xserviced a request, just in case another request comes in.  In the
  502. Xinetd configuration file these daemons are registered with the `wait'
  503. Xoption. Only the request that started such a daemon will be seen by the
  504. Xwrappers.  This restriction does not apply to connection-oriented (TCP)
  505. Xservices.
  506. X
  507. XTLI (transport level interface), the System V stream-based and
  508. Xprotocol-independent network programming interface, is not yet
  509. Xsupported, but we're working on it.
  510. X
  511. XThe wrappers do not work with RPC services over TCP. These services are
  512. Xregistered as rpc/tcp in the inetd configuration file. The only non-
  513. Xtrivial service that is affected by this limitation is rexd, which is
  514. Xused by the on(1) command. This is no great loss.  On most systems,
  515. Xrexd is less secure than a wildcard in /etc/hosts.equiv.
  516. X
  517. XRPC broadcast requests (for example: rwall, rup, rusers) always appear
  518. Xto come from the responding host. What happens is that the client
  519. Xbroadcasts its request to all portmap daemons on its network; each
  520. Xportmap daemon forwards the request to its own system. As far as the
  521. Xrwall etc.  daemons know, the request comes from the local host.
  522. X
  523. XPortmap and RPC (e.g. NIS and NFS) security is a topic in itself. See
  524. Xthe section in this document on related software.
  525. X
  526. X6.2 - Known system software bugs
  527. X--------------------------------
  528. X
  529. XWorkarounds have been implemented for several bugs in system software.
  530. XThey are described in the Makefile. Unfortunately, some system software
  531. Xbugs cannot be worked around. The result is loss of functionality.
  532. X
  533. XOlder ConvexOS versions come with a broken recvfrom(2) implementation.
  534. XThis makes it impossible for the daemon wrappers to look up the
  535. Xremote host address (and hence, the name) in case of UDP requests.
  536. XA patch is available for ConvexOS 10.1; later releases should be OK.
  537. X
  538. XOn some systems, the optional RFC 931 remote username lookups may
  539. Xtrigger a kernel bug.  When a client host connects to your system, and
  540. Xthe RFC 931 connection from your system to that client is rejected by a
  541. Xrouter, your kernel may drop all connections with that client.  This is
  542. Xnot a bug in the wrapper programs: complain to your vendor, and don't
  543. Xenable remote user name lookups until the bug has been fixed.
  544. X
  545. XReportedly, SunOS 4.1.1, Next 2.0a, ISC 3.0 with TCP 1.3, and AIX 3.2.2
  546. Xare OK.
  547. X
  548. XSony News/OS 4.51, HP-UX 8-something and Ultrix 4.3 still have the bug.
  549. XAt the time of writing, a fix for Ultrix is being field tested (CXO-8919).
  550. X
  551. XThe following procedure can be used (from outside the tue.nl domain) to
  552. Xfind out if your kernel has the bug. From the system under test, do:
  553. X
  554. X    % ftp 131.155.70.100
  555. X
  556. XThis command attempts to make an ftp connection to our anonymous ftp
  557. Xserver (ftp.win.tue.nl).  When the connection has been established, run
  558. Xthe following command from the same system under test, while keeping
  559. Xthe ftp connection open:
  560. X
  561. X    % telnet 131.155.70.100 111
  562. X
  563. XDo not forget the `111' at the end of the command. This telnet command
  564. Xattempts to connect to our portmap process.  The telnet command should
  565. Xfail with:  "host not reachable", or something like that. If your ftp
  566. Xconnection gets messed up, you have the bug. If the telnet command does
  567. Xnot fail, please let me know a.s.a.p.!
  568. X
  569. XFor those who care, the bug is that the BSD kernel code was not careful
  570. Xenough with incoming ICMP UNREACHABLE control messages (it ignored the
  571. Xlocal and remote port numbers). The bug is still present in the BSD
  572. XNET/1 source release (1989) but apparently has been fixed in BSD NET/2
  573. X(1991). You can see it with your own eyes, if you have the courage.
  574. X
  575. X7 - Configuration and installation
  576. X----------------------------------
  577. X
  578. X7.1 - Easy configuration and installation
  579. X-----------------------------------------
  580. X
  581. XThe "easy" recipe requires no changes to existing software or
  582. Xconfiguration files.  Basically, you move the daemons that you want to
  583. Xprotect to a different directory and plug the resulting holes with
  584. Xcopies of the wrapper programs.
  585. X
  586. XIf you don't run Ultrix, you won't need the miscd wrapper program.  The
  587. Xmiscd daemon implements among others the SYSTAT service, which produces
  588. Xthe same output as the the WHO command.
  589. X
  590. XCopy the file Makefile.dist to Makefile, edit the Makefile according to
  591. Xthe instructions at the beginning of that file, and type `make'. 
  592. X
  593. XWhen the `make' succeeds the result is two executables (maybe three in
  594. Xcase of Ultrix). The `try' program can be used to play with host access
  595. Xcontrol tables and is described in a later section.
  596. X
  597. XThe tcpd program can be used to monitor the telnet, finger, ftp, exec,
  598. Xrsh, rlogin, tftp, talk, comsat and other tcp or udp services that have
  599. Xa one-to-one mapping onto executable files.
  600. X
  601. XThe tcpd program can also be used for services that are marked as
  602. Xrpc/udp in the inetd configuration file, but not for rpc/tcp services
  603. Xsuch as rexd.  You probably do not want to run rexd anyway. On most
  604. Xsystems it is even less secure than a wildcard in /etc/hosts.equiv.
  605. X
  606. XThe wrappers are not yet able to deal with TLI-based services.
  607. X
  608. XDecide which services you want to monitor. Move the corresponding
  609. Xvendor-provided daemon programs to the location specified by the
  610. XREAL_DAEMON_DIR constant in the Makefile, and fill the holes with
  611. Xcopies of the tcpd wrapper. That is, one copy of (or link to) the tcpd
  612. Xprogram for each service that you want to monitor. For example, to
  613. Xmonitor the use of your finger service:
  614. X
  615. X    # mkdir REAL_DAEMON_DIR
  616. X    # mv /usr/etc/in.fingerd REAL_DAEMON_DIR
  617. X    # cp tcpd /usr/etc/in.fingerd
  618. X
  619. XThe example applies to SunOS 4. With other UNIX implementations the
  620. Xnetwork daemons live in /usr/libexec or /usr/sbin, or have no "in."
  621. Xprefix to their names, but you get the idea.
  622. X
  623. XUltrix only:  If you want to monitor the SYSTAT service, move the
  624. Xvendor-provided miscd daemon to the location specified by the
  625. XREAL_MISCD macro in the Makefile, and install the miscd wrapper into
  626. Xthe original miscd location.
  627. X
  628. XIn the absence of any access-control tables, the daemon wrappers
  629. Xwill just maintain a record of network connections made to your system.
  630. X
  631. X7.2 - Advanced configuration and installation
  632. X---------------------------------------------
  633. X
  634. XThe advanced recipe leaves your daemon executables alone, but involves
  635. Xsimple modifications to the inetd configuration file.
  636. X
  637. XCopy the file Makefile.dist to Makefile.  In the Makefile, define the
  638. XREAL_DAEMON_DIR macro (if you run Ultrix, the REAL_MISCD macro, too) to
  639. Xreflect the path to your existing network daemons. Don't panic when
  640. Xsome daemons live elsewhere; we'll deal with that later.  Have a look
  641. Xat the other instructions in the Makefile and type `make'.
  642. X
  643. XWhen the `make' succeeds the result is two executables (maybe three in
  644. Xcase of Ultrix). The `try' program can be used to play with host access
  645. Xcontrol tables and is described in a later section.
  646. X
  647. XThe tcpd program can be used to monitor the telnet, finger, ftp, exec,
  648. Xrsh, rlogin, tftp, talk, comsat and other tcp or udp services that have
  649. Xa one-to-one mapping onto executable files.
  650. X
  651. XThe tcpd program can also be used for services that are marked as
  652. Xrpc/udp in the inetd configuration file, but not for rpc/tcp services
  653. Xsuch as rexd.  You probably do not want to run rexd anyway. On most
  654. Xsystems it is even less secure than a wildcard in /etc/hosts.equiv.
  655. X
  656. XThe wrappers are not yet able to deal with TLI-based services.
  657. X
  658. XInstall the tcpd command in a suitable place. Apollo UNIX users will
  659. Xwant to install it under a different name because the name "tcpd" is
  660. Xalready taken; a suitable name for the wrapper program would be
  661. X"frontd".  Then perform the following edits on the inetd configuration
  662. Xfile (usually /etc/inetd.conf or /etc/inet/inetd.conf):
  663. X
  664. X    finger  stream  tcp     nowait  nobody  /usr/etc/in.fingerd     in.fingerd
  665. X
  666. Xbecomes:
  667. X
  668. X    finger  stream  tcp     nowait  nobody  /usr/etc/tcpd           in.fingerd
  669. X
  670. XSend a `kill -HUP' to the inetd process to make the change effective.
  671. X
  672. XThe example applies to SunOS 4. With other UNIX implementations the
  673. Xnetwork daemons live in /usr/libexec or /usr/sbin, the network daemons
  674. Xhave no "in." prefix to their names, or the username field in the inetd
  675. Xconfiguration file may be missing.
  676. X
  677. XWhen the finger service works as expected you can perform similar
  678. Xchanges for other network services. Do not forget the `kill -HUP'.
  679. X
  680. XThe miscd daemon that comes with Ultrix implements several network
  681. Xservices. It decides what to do by looking at its process name. One of
  682. Xthe services is systat, which is a kind of limited finger service.  If
  683. Xyou want to monitor the systat service, install the miscd wrapper in
  684. Xa suitable place and update the inetd configuration file:
  685. X
  686. X    systat  stream  tcp     nowait  /suitable/place/miscd      systatd
  687. X
  688. XUltrix 4.3 allows you to specify a user id under which the daemon will
  689. Xbe executed. This feature is not documented in the manual pages.  Thus,
  690. Xthe example would become:
  691. X
  692. X    systat  stream  tcp     nowait  nobody /suitable/place/miscd    systatd
  693. X
  694. XOlder Ultrix systems still run all their network daemons as root.
  695. X
  696. XIn the absence of any access-control tables, the daemon wrappers
  697. Xwill just maintain a record of network connections made to your system.
  698. X
  699. X7.3 - Daemons with arbitrary path names
  700. X---------------------------------------
  701. X
  702. XThe above tcpd examples work fine with network daemons that live in a
  703. Xcommon directory, but sometimes that is not practical. Having soft
  704. Xlinks all over your file system is not a clean solution, either.
  705. X
  706. XInstead you can specify, in the inetd configuration file, an absolute
  707. Xpath name for the daemon process name.  For example,
  708. X
  709. X    ntalk   dgram   udp     wait    root    /usr/etc/tcpd /usr/local/lib/ntalkd
  710. X
  711. XWhen the daemon process name is an absolute path name, tcpd ignores the
  712. Xvalue of the REAL_DAEMON_DIR constant, and uses the last path component
  713. Xof the daemon process name for logging and for access control.
  714. X
  715. X7.4 - Building and testing the access control rules
  716. X---------------------------------------------------
  717. X
  718. XIn order to support access control the wrappers must be compiled with
  719. Xthe -DHOSTS_ACCESS option. The access control policy is given in the
  720. Xform of two tables (default: /etc/hosts.allow and /etc/hosts.deny).
  721. XAccess control is disabled when there are no access control tables, or
  722. Xwhen the tables are empty.
  723. X
  724. XIf you haven't used the wrappers before I recommend that you first run
  725. Xthem a couple of days without any access control restrictions. The
  726. Xlogfile records should give you an idea of the process names and of the
  727. Xhost names that you will have to build into your access control rules.
  728. X
  729. XThe syntax of the access control rules is documented in the file
  730. Xhosts_access.5, which is in `nroff -man' format. This is a lengthy
  731. Xdocument, and no-one expects you to read it right away from beginning
  732. Xto end.  Instead, after reading the introductory section, skip to the
  733. Xexamples at the end so that you get a general idea of the language.
  734. XThen you can appreciate the detailed reference sections near the
  735. Xbeginning of the document.
  736. X
  737. XThe examples in the hosts_access.5 document show two specific types of
  738. Xaccess control policy:  1) mostly closed (only permitting access from a
  739. Xlimited number of systems) and 2) mostly open (permitting access from
  740. Xeveryone except a limited number of trouble makers). You will have to
  741. Xchoose what model suits your situation best. Implementing a mixed
  742. Xpolicy should not be overly difficult either.
  743. X
  744. XThe `try' command can be used to try out your local access control
  745. Xfiles.  The command syntax is:
  746. X
  747. X    ./try process_name hostname    (e.g.: ./try in.tftpd localhost)
  748. X
  749. X    ./try process_name address    (e.g.: ./try in.tftpd 127.0.0.1)
  750. X
  751. XIn order to find out what process name to use, just use the service and
  752. Xwatch the process name that shows up in the logfile.  Alternatively,
  753. Xyou can look up the name from the inetd configuration file. Coming back
  754. Xto the tftp example in the tutorial section above:
  755. X
  756. X    tftp  dgram  udp  wait  root  /usr/etc/tcpd  in.tftpd -s /tftpboot
  757. X
  758. XThis entry causes the inetd to run the wrapper program (tcpd) with a
  759. Xprocess name `in.tftpd'.  This is the name that the wrapper will use
  760. Xwhen scanning the access control tables. Therefore, `in.tftpd' is the
  761. Xprocess name that should be given to the `try' command. On your system
  762. Xthe actual inetd.conf entry may differ (tftpd instead of in.tftpd, and
  763. Xno `root' field), but you get the idea.
  764. X
  765. XWhen you specify a host name, the `try' program will use both the host
  766. Xname and address. This way you can simulate the most common case where
  767. Xthe wrappers know both the host address and the host name.  The `try'
  768. Xprogram will iterate over all addresses that it can find for the given
  769. Xhost name.
  770. X
  771. XWhen you specify a host address instead of a host name, the `try'
  772. Xprogram will pretend that the host name is unknown, so that you can
  773. Xsimulate what happens when the wrapper is unable to look up the remote
  774. Xhost name.
  775. X
  776. XSerious errors in the configuration file syntax will be reported via
  777. Xthe syslog daemon.  Run a `tail -f' on the logfile while playing with
  778. Xthe `try' command. The tutorial section at the beginning of this file
  779. Xdescribes where to look for your logfile.
  780. X
  781. X7.5 - Other applications
  782. X------------------------
  783. X
  784. XThe access control routines can easily be integrated with other
  785. Xprograms.  The hosts_access.3 manual page (`nroff -man' format)
  786. Xdescribes the external interface of the libwrap.a library.
  787. X
  788. XThe tcpd wrapper can even be used to control access to the smtp port.
  789. XIn that case, sendmail should not be run as a stand-alone daemon, but
  790. Xit should be registered in the inetd configuration file. For example:
  791. X
  792. X    smtp    stream  tcp     nowait  root    /usr/etc/tcpd /usr/lib/sendmail -bs
  793. X
  794. XYou will periodically want to run sendmail to process queued-up
  795. Xmessages. A crontab entry like:
  796. X
  797. X    0,15,30,45 * * * * /usr/lib/sendmail -q
  798. X
  799. Xshould take care of that. When you are going to "protect" your sendmail
  800. Xdaemon this way, you should realize that there are many "unprotected"
  801. Xsendmail daemons all over the network that can still be abused.
  802. X
  803. X8 - Acknowledgements
  804. X--------------------
  805. X
  806. XMany people contributed to the evolution of the programs, by asking
  807. Xinspiring questions, by suggesting features or bugfixes, or by
  808. Xsubmitting source code.  Nevertheless, all mistakes and bugs in the
  809. Xwrappers are my own.
  810. X
  811. XThanks to Brendan Kehoe (brendan@cs.widener.edu), Heimir Sverrisson
  812. X(heimir@hafro.is) and Dan Bernstein (brnstnd@kramden.acf.nyu.edu) for
  813. Xfeedback on an early release of this product.  The host name/address
  814. Xcheck was suggested by John Kimball (jkimball@src.honeywell.com).
  815. XApollo's UNIX environment has some peculiar quirks: Willem-Jan Withagen
  816. X(wjw@eb.ele.tue.nl), Pieter Schoenmakers (tiggr@es.ele.tue.nl) and
  817. XCharles S. Fuller (fuller@wccs.psc.edu) provided assistance.  Hal R.
  818. XBrand (BRAND@addvax.llnl.gov) told me how to get the remote IP address
  819. Xin case of datagram-oriented services, and suggested the optional shell
  820. Xcommand feature.  Shabbir Safdar (shabby@mentor.cc.purdue.edu) provided
  821. Xa first version of a much-needed manual page.  Granville Boman Goza, IV
  822. X(gbg@sei.cmu.edu) suggested to use the remote IP address even when the
  823. Xhost name is available.  Casper H.S. Dik (casper@fwi.uva.nl) provided
  824. Xadditional insight into DNS spoofing techniques.  The bogus daemon
  825. Xfeature was inspired by code from Andrew Macpherson (BNR Europe Ltd).
  826. XSteve Bellovin (smb@research.att.com) confirmed some of my suspicions
  827. Xabout the darker sides of TCP/IP insecurity.
  828. X
  829. XIn no particular order, Howard Chu (hyc@hanauma.jpl.nasa.gov), John P.
  830. XRouillard (rouilj@cs.umb.edu), Darren Reed (avalon@coombs.anu.edu.au),
  831. XIcarus Sparry (I.Sparry@gdr.bath.ac.uk), Scott Schwartz (schwartz@
  832. Xcs.psu.edu), John A. Kunze (jak@violet.berkeley.edu), Daniel Len
  833. XSchales (dan@engr.latech.edu), Chris Turbeville <turbo@cse.uta.edu>,
  834. XPaul Kranenburg <pk@cs.few.eur.nl>, and many, many others provided
  835. Xfixes, code fragments, or other improvements to the wrappers.
  836. X
  837. X    Wietse Venema (wietse@wzv.win.tue.nl)
  838. X    Department of Mathematics and Computing Science
  839. X    Eindhoven University of Technology
  840. X    P.O. Box 513
  841. X    5600 MB Eindhoven
  842. X    The Netherlands
  843. END_OF_README
  844. if test 34888 -ne `wc -c <README`; then
  845.     echo shar: \"README\" unpacked with wrong size!
  846. fi
  847. # end of overwriting check
  848. fi
  849. if test -f miscd.c -a "${1}" != "-c" ; then 
  850.   echo shar: Will not over-write existing file \"miscd.c\"
  851. else
  852. echo shar: Extracting \"miscd.c\" \(2602 characters\)
  853. sed "s/^X//" >miscd.c <<'END_OF_miscd.c'
  854. X /*
  855. X  * Front end to the ULTRIX miscd service. The front end logs the remote host
  856. X  * name and then invokes the real miscd daemon. Install as "/usr/etc/miscd",
  857. X  * after moving the real miscd daemon to the "/usr/etc/..." directory.
  858. X  * Connections and diagnostics are logged through syslog(3).
  859. X  * 
  860. X  * The Ultrix miscd program implements (among others) the systat service, which
  861. X  * pipes the output from who(1) to stdout. This information is potentially
  862. X  * useful to systems crackers.
  863. X  * 
  864. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  865. X  */
  866. X
  867. X#ifndef lint
  868. Xstatic char sccsid[] = "@(#) miscd.c 1.4 93/03/07 22:47:28";
  869. X#endif
  870. X
  871. X/* System libraries. */
  872. X
  873. X#include <sys/types.h>
  874. X#include <sys/param.h>
  875. X#include <sys/stat.h>
  876. X#include <stdio.h>
  877. X#include <syslog.h>
  878. X
  879. X/* Local stuff. */
  880. X
  881. X#include "patchlevel.h"
  882. X#include "log_tcp.h"
  883. X
  884. X/* The following specifies where the vendor-provided daemon should go. */
  885. X
  886. X#ifndef REAL_MISCD
  887. X#define REAL_MISCD    "/usr/etc/.../miscd"
  888. X#endif
  889. X
  890. Xint     log_severity = SEVERITY;    /* run-time adjustable */
  891. X
  892. Xmain(argc, argv)
  893. Xint     argc;
  894. Xchar  **argv;
  895. X{
  896. X    struct from_host from;
  897. X    int     from_stat;
  898. X
  899. X    /* Attempt to prevent the creation of world-writable files. */
  900. X
  901. X#ifdef DAEMON_UMASK
  902. X    umask(DAEMON_UMASK);
  903. X#endif
  904. X
  905. X    /*
  906. X     * Open a channel to the syslog daemon. Older versions of openlog()
  907. X     * require only two arguments.
  908. X     */
  909. X
  910. X#ifdef LOG_MAIL
  911. X    (void) openlog(argv[0], LOG_PID, FACILITY);
  912. X#else
  913. X    (void) openlog(argv[0], LOG_PID);
  914. X#endif
  915. X
  916. X    /*
  917. X     * Find out and verify the remote host name. Sites concerned with
  918. X     * security may choose to refuse connections from hosts that pretend to
  919. X     * have someone elses host name.
  920. X     */
  921. X
  922. X    from_stat = fromhost(&from);
  923. X#ifdef PARANOID
  924. X    if (from_stat == -1)
  925. X    refuse(&from);
  926. X#endif
  927. X
  928. X    /*
  929. X     * The BSD rlogin and rsh daemons that came out after 4.3 BSD disallow
  930. X     * socket options at the IP level. They do so for a good reason. Let's
  931. X     * follow their example.
  932. X     */
  933. X
  934. X#ifdef KILL_IP_OPTIONS
  935. X    fix_options(&from);
  936. X#endif
  937. X
  938. X    /*
  939. X     * Check whether this host can access the service in argv[0]. The
  940. X     * access-control code invokes optional shell commands as specified in
  941. X     * the access-control tables.
  942. X     */
  943. X
  944. X#ifdef HOSTS_ACCESS
  945. X    if (!hosts_access(argv[0], &from))
  946. X    refuse(&from);
  947. X#endif
  948. X
  949. X    /* Report remote client and invoke the real daemon program. */
  950. X
  951. X    syslog(log_severity, "connect from %s", hosts_info(&from));
  952. X    (void) execv(REAL_MISCD, argv);
  953. X    syslog(LOG_ERR, "%s: %m", REAL_MISCD);
  954. X    clean_exit(&from);
  955. X    /* NOTREACHED */
  956. X}
  957. END_OF_miscd.c
  958. if test 2602 -ne `wc -c <miscd.c`; then
  959.     echo shar: \"miscd.c\" unpacked with wrong size!
  960. fi
  961. # end of overwriting check
  962. fi
  963. if test -f tcpd.c -a "${1}" != "-c" ; then 
  964.   echo shar: Will not over-write existing file \"tcpd.c\"
  965. else
  966. echo shar: Extracting \"tcpd.c\" \(2995 characters\)
  967. sed "s/^X//" >tcpd.c <<'END_OF_tcpd.c'
  968. X /*
  969. X  * General front end for stream and datagram IP services. This program logs
  970. X  * the remote host name and then invokes the real daemon. For example,
  971. X  * install as /usr/etc/{tftpd,fingerd,telnetd,ftpd,rlogind,rshd,rexecd},
  972. X  * after saving the real daemons in the directory "/usr/etc/...". This
  973. X  * arrangement requires that the network daemons are started by inetd or
  974. X  * something similar. Connections and diagnostics are logged through
  975. X  * syslog(3).
  976. X  * 
  977. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  978. X  */
  979. X
  980. X#ifndef lint
  981. Xstatic char sccsid[] = "@(#) tcpd.c 1.4 93/03/07 22:47:32";
  982. X#endif
  983. X
  984. X/* System libraries. */
  985. X
  986. X#include <sys/types.h>
  987. X#include <sys/param.h>
  988. X#include <sys/stat.h>
  989. X#include <stdio.h>
  990. X#include <syslog.h>
  991. X
  992. Xextern char *strrchr();
  993. Xextern char *strcpy();
  994. X
  995. X#ifndef MAXPATHNAMELEN
  996. X#define MAXPATHNAMELEN    BUFSIZ
  997. X#endif
  998. X
  999. X/* Local stuff. */
  1000. X
  1001. X#include "patchlevel.h"
  1002. X#include "log_tcp.h"
  1003. X
  1004. X/* The following specifies where the vendor-provided daemons should go. */
  1005. X
  1006. X#ifndef REAL_DAEMON_DIR
  1007. X#define REAL_DAEMON_DIR    "/usr/etc/..."
  1008. X#endif
  1009. X
  1010. Xint     log_severity = SEVERITY;    /* run-time adjustable */
  1011. X
  1012. Xmain(argc, argv)
  1013. Xint     argc;
  1014. Xchar  **argv;
  1015. X{
  1016. X    struct from_host from;
  1017. X    int     from_stat;
  1018. X    char    path[MAXPATHNAMELEN];
  1019. X
  1020. X    /* Attempt to prevent the creation of world-writable files. */
  1021. X
  1022. X#ifdef DAEMON_UMASK
  1023. X    umask(DAEMON_UMASK);
  1024. X#endif
  1025. X
  1026. X    /*
  1027. X     * If argv[0] is an absolute path name, ignore REAL_DAEMON_DIR, and strip
  1028. X     * argv[0] to its basename.
  1029. X     */
  1030. X
  1031. X    if (argv[0][0] == '/') {
  1032. X    strcpy(path, argv[0]);
  1033. X    argv[0] = strrchr(argv[0], '/') + 1;
  1034. X    } else {
  1035. X    sprintf(path, "%s/%s", REAL_DAEMON_DIR, argv[0]);
  1036. X    }
  1037. X
  1038. X    /*
  1039. X     * Open a channel to the syslog daemon. Older versions of openlog()
  1040. X     * require only two arguments.
  1041. X     */
  1042. X
  1043. X#ifdef LOG_MAIL
  1044. X    (void) openlog(argv[0], LOG_PID, FACILITY);
  1045. X#else
  1046. X    (void) openlog(argv[0], LOG_PID);
  1047. X#endif
  1048. X
  1049. X    /*
  1050. X     * Find out and verify the remote host name. Sites concerned with
  1051. X     * security may choose to refuse connections from hosts that pretend to
  1052. X     * have someone elses host name.
  1053. X     */
  1054. X
  1055. X    from_stat = fromhost(&from);
  1056. X#ifdef PARANOID
  1057. X    if (from_stat == -1)
  1058. X    refuse(&from);
  1059. X#endif
  1060. X
  1061. X    /*
  1062. X     * The BSD rlogin and rsh daemons that came out after 4.3 BSD disallow
  1063. X     * socket options at the IP level. They do so for a good reason. Let's
  1064. X     * follow their example.
  1065. X     */
  1066. X
  1067. X#ifdef KILL_IP_OPTIONS
  1068. X    fix_options(&from);
  1069. X#endif
  1070. X
  1071. X    /*
  1072. X     * Check whether this host can access the service in argv[0]. The
  1073. X     * access-control code invokes optional shell commands as specified in
  1074. X     * the access-control tables.
  1075. X     */
  1076. X
  1077. X#ifdef HOSTS_ACCESS
  1078. X    if (!hosts_access(argv[0], &from))
  1079. X    refuse(&from);
  1080. X#endif
  1081. X
  1082. X    /* Report remote client and invoke the real daemon program. */
  1083. X
  1084. X    syslog(log_severity, "connect from %s", hosts_info(&from));
  1085. X    (void) execv(path, argv);
  1086. X    syslog(LOG_ERR, "%s: %m", path);
  1087. X    clean_exit(&from);
  1088. X    /* NOTREACHED */
  1089. X}
  1090. END_OF_tcpd.c
  1091. if test 2995 -ne `wc -c <tcpd.c`; then
  1092.     echo shar: \"tcpd.c\" unpacked with wrong size!
  1093. fi
  1094. # end of overwriting check
  1095. fi
  1096. if test -f fromhost.c -a "${1}" != "-c" ; then 
  1097.   echo shar: Will not over-write existing file \"fromhost.c\"
  1098. else
  1099. echo shar: Extracting \"fromhost.c\" \(8144 characters\)
  1100. sed "s/^X//" >fromhost.c <<'END_OF_fromhost.c'
  1101. X /*
  1102. X  * fromhost() determines the type of connection (datagram, stream), the name
  1103. X  * and address of the host at the other end of standard input, and the
  1104. X  * remote user name (if RFC 931 lookups are enabled). A host name of "stdin"
  1105. X  * is returned if the program is run from a tty. The value "unknown" is
  1106. X  * returned as a placeholder for information that could not be looked up.
  1107. X  * All results are in static memory.
  1108. X  * 
  1109. X  * The return status is (-1) if the remote host pretends to have someone elses
  1110. X  * host name, otherwise a zero status is returned.
  1111. X  * 
  1112. X  * Diagnostics are reported through syslog(3).
  1113. X  * 
  1114. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  1115. X  */
  1116. X
  1117. X#ifndef lint
  1118. Xstatic char sccsid[] = "@(#) fromhost.c 1.7 93/03/07 22:47:34";
  1119. X#endif
  1120. X
  1121. X/* System libraries. */
  1122. X
  1123. X#include <sys/types.h>
  1124. X#include <sys/param.h>
  1125. X#include <sys/socket.h>
  1126. X#include <netinet/in.h>
  1127. X#include <netdb.h>
  1128. X#include <stdio.h>
  1129. X#include <syslog.h>
  1130. X#include <errno.h>
  1131. X
  1132. Xextern char *inet_ntoa();
  1133. Xextern char *strncpy();
  1134. Xextern char *strcpy();
  1135. X
  1136. X/* In case not defined in <sys/param.h>. */
  1137. X
  1138. X#ifndef MAXHOSTNAMELEN
  1139. X#define MAXHOSTNAMELEN    1024        /* string with host name */
  1140. X#endif
  1141. X
  1142. X/* Local stuff. */
  1143. X
  1144. X#include "log_tcp.h"
  1145. X
  1146. X/* Forward declarations. */
  1147. X
  1148. Xstatic int matchname();
  1149. X
  1150. X/* The following are to be used in assignment context, not in comparisons. */
  1151. X
  1152. X#define    GOOD    1
  1153. X#define    BAD    0
  1154. X
  1155. X/* Initially, we know nothing about the origin of the connection. */
  1156. X
  1157. Xstatic struct from_host from_unknown = {
  1158. X    0,                    /* connected/unconnected */
  1159. X    FROM_UNKNOWN,            /* remote host name */
  1160. X    FROM_UNKNOWN,            /* remote host address */
  1161. X    "",                    /* remote user name */
  1162. X};
  1163. X
  1164. X /*
  1165. X  * With early SunOS 5 versions, recvfrom() does not completely fill in the
  1166. X  * source address structure when doing a non-destructive read. The following
  1167. X  * code works around the problem. It does no harm on "normal" systems.
  1168. X  */
  1169. X
  1170. X#ifdef RECVFROM_BUG
  1171. X
  1172. Xstatic int fix_recvfrom(sock, buf, buflen, flags, from, fromlen)
  1173. Xint     sock;
  1174. Xchar   *buf;
  1175. Xint     buflen;
  1176. Xint     flags;
  1177. Xstruct sockaddr *from;
  1178. Xint     *fromlen;
  1179. X{
  1180. X    int     ret;
  1181. X
  1182. X    /* Assume that both ends of a socket belong to the same address family. */
  1183. X
  1184. X    if ((ret = recvfrom(sock, buf, buflen, flags, from, fromlen)) >= 0) {
  1185. X    if (from->sa_family == 0) {
  1186. X        struct sockaddr my_addr;
  1187. X        int     my_addr_len = sizeof(my_addr);
  1188. X
  1189. X        if (getsockname(0, &my_addr, &my_addr_len)) {
  1190. X        syslog(LOG_ERR, "getsockname: %m");
  1191. X        } else {
  1192. X        from->sa_family = my_addr.sa_family;
  1193. X        }
  1194. X    }
  1195. X    }
  1196. X    return (ret);
  1197. X}
  1198. X
  1199. X#define recvfrom fix_recvfrom
  1200. X#endif
  1201. X
  1202. X /*
  1203. X  * The Apollo SR10.3 and some SYSV4 getpeername(2) versions do not return an
  1204. X  * error in case of a datagram-oriented socket. Instead, they claim that all
  1205. X  * UDP requests come from address 0.0.0.0. The following code works around
  1206. X  * the problem. It does no harm on "normal" systems.
  1207. X  */
  1208. X
  1209. X#ifdef GETPEERNAME_BUG
  1210. X
  1211. Xstatic int fix_getpeername(sock, sa, len)
  1212. Xint     sock;
  1213. Xstruct sockaddr *sa;
  1214. Xint    *len;
  1215. X{
  1216. X    int     ret;
  1217. X    struct sockaddr_in *sin = (struct sockaddr_in *) sa;
  1218. X
  1219. X    if ((ret = getpeername(sock, sa, len)) >= 0
  1220. X    && sa->sa_family == AF_INET
  1221. X    && sin->sin_addr.s_addr == 0) {
  1222. X    errno = ENOTCONN;
  1223. X    return (-1);
  1224. X    } else {
  1225. X    return (ret);
  1226. X    }
  1227. X}
  1228. X
  1229. X#define    getpeername    fix_getpeername
  1230. X#endif
  1231. X
  1232. X/* fromhost - find out what is at the other end of standard input */
  1233. X
  1234. Xint     fromhost(f)
  1235. Xstruct from_host *f;
  1236. X{
  1237. X    static struct sockaddr sa;
  1238. X    struct sockaddr_in *sin = (struct sockaddr_in *) (&sa);
  1239. X    struct hostent *hp;
  1240. X    int     length = sizeof(sa);
  1241. X    char    buf[BUFSIZ];
  1242. X    static char addr_buf[FROM_ADDRLEN];
  1243. X    static char name_buf[MAXHOSTNAMELEN];
  1244. X
  1245. X    /*
  1246. X     * There are so many results and so many early returns that it seems
  1247. X     * safest to first initialize all results to UNKNOWN.
  1248. X     */
  1249. X
  1250. X    *f = from_unknown;
  1251. X
  1252. X    /*
  1253. X     * Look up the remote host address. Hal R. Brand <BRAND@addvax.llnl.gov>
  1254. X     * suggested how to get the remote host info in case of UDP connections:
  1255. X     * peek at the first message without actually looking at its contents.
  1256. X     */
  1257. X
  1258. X    if (getpeername(0, &sa, &length) >= 0) {    /* assume TCP request */
  1259. X    f->sock_type = FROM_CONNECTED;
  1260. X    } else {
  1261. X    switch (errno) {
  1262. X    default:
  1263. X        if (isatty(0))            /* stdin is not a socket */
  1264. X        f->name = "stdin";
  1265. X        else
  1266. X        syslog(LOG_ERR, "getpeername: %m");    /* other, punt */
  1267. X        return (0);
  1268. X    case ENOTCONN:                /* assume UDP request */
  1269. X        length = sizeof(sa);
  1270. X        if (recvfrom(0, buf, sizeof(buf), MSG_PEEK, &sa, &length) < 0) {
  1271. X        syslog(LOG_ERR, "recvfrom: %m");
  1272. X        return (0);
  1273. X        }
  1274. X#ifdef really_paranoid
  1275. X        memset(buf, 0 sizeof(buf));
  1276. X#endif
  1277. X        f->sock_type = FROM_UNCONNECTED;
  1278. X        break;
  1279. X    }
  1280. X    }
  1281. X
  1282. X    /*
  1283. X     * At present, we can only deal with the AF_INET address family. Some
  1284. X     * implementations of System V religion never fill in the address family
  1285. X     * field in case of UDP connections. If that happens, you may want to
  1286. X     * take the chance and assume that we're dealing with TCP/IP anyway.
  1287. X     */
  1288. X
  1289. X#ifdef ADDRESS_FAMILY_BUG
  1290. X    if (sa.sa_family == 0)
  1291. X    sa.sa_family = AF_INET;
  1292. X#endif
  1293. X    if (sa.sa_family != AF_INET) {
  1294. X    syslog(LOG_ERR, "unexpected address family %ld", (long) sa.sa_family);
  1295. X    return (0);
  1296. X    }
  1297. X    /* Save the host address. A later inet_ntoa() call may clobber it. */
  1298. X
  1299. X    f->sin = sin;
  1300. X    f->addr = strcpy(addr_buf, inet_ntoa(sin->sin_addr));
  1301. X
  1302. X    /* Look up the remote user name. Does not work for UDP services. */
  1303. X
  1304. X#if defined(RFC931) && !defined(USER_AT_HOST) && !defined(RFC931_OPTION)
  1305. X    if (f->sock_type == FROM_CONNECTED)
  1306. X    f->user = rfc931_name(sin);
  1307. X#endif
  1308. X
  1309. X    /* Look up the remote host name. */
  1310. X
  1311. X    if ((hp = gethostbyaddr((char *) &sin->sin_addr,
  1312. X                sizeof(sin->sin_addr),
  1313. X                AF_INET)) == 0) {
  1314. X    return (0);
  1315. X    }
  1316. X    /* Save the host name. A later gethostbyxxx() call may clobber it. */
  1317. X
  1318. X    f->name = strncpy(name_buf, hp->h_name, sizeof(name_buf) - 1);
  1319. X    name_buf[sizeof(name_buf) - 1] = 0;
  1320. X
  1321. X    /*
  1322. X     * Verify that the host name does not belong to someone else. If host
  1323. X     * name verification fails, pretend that the host name lookup failed.
  1324. X     */
  1325. X
  1326. X    if (matchname(f->name, sin->sin_addr)) {
  1327. X    return (0);
  1328. X    } else {
  1329. X    f->name = FROM_UNKNOWN;
  1330. X    return (-1);                /* verification failed */
  1331. X    }
  1332. X}
  1333. X
  1334. X/* matchname - determine if host name matches IP address */
  1335. X
  1336. Xstatic int matchname(remotehost, addr)
  1337. Xchar   *remotehost;
  1338. Xstruct in_addr addr;
  1339. X{
  1340. X    struct hostent *hp;
  1341. X    int     i;
  1342. X
  1343. X    if ((hp = gethostbyname(remotehost)) == 0) {
  1344. X
  1345. X    /*
  1346. X     * Unable to verify that the host name matches the address. This may
  1347. X     * be a transient problem or a botched name server setup. We decide
  1348. X     * to play safe.
  1349. X     */
  1350. X
  1351. X    syslog(LOG_ERR, "gethostbyname(%s): lookup failure", remotehost);
  1352. X    return (BAD);
  1353. X
  1354. X    } else {
  1355. X
  1356. X    /*
  1357. X     * Make sure that gethostbyname() returns the "correct" host name.
  1358. X     * Unfortunately, gethostbyname("localhost") sometimes yields
  1359. X     * "localhost.domain". Since the latter host name comes from the
  1360. X     * local DNS, we just have to trust it (all bets are off if the local
  1361. X     * DNS is perverted). We always check the address list, though.
  1362. X     */
  1363. X
  1364. X    if (strcasecmp(remotehost, hp->h_name)
  1365. X        && strcasecmp(remotehost, "localhost")) {
  1366. X        syslog(LOG_ERR, "host name/name mismatch: %s != %s",
  1367. X           remotehost, hp->h_name);
  1368. X        return (BAD);
  1369. X    }
  1370. X    /* Look up the host address in the address list we just got. */
  1371. X
  1372. X    for (i = 0; hp->h_addr_list[i]; i++) {
  1373. X        if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
  1374. X        return (GOOD);
  1375. X    }
  1376. X
  1377. X    /*
  1378. X     * The host name does not map to the original host address. Perhaps
  1379. X     * someone has compromised a name server. More likely someone botched
  1380. X     * it, but that could be dangerous, too.
  1381. X     */
  1382. X
  1383. X    syslog(LOG_ERR, "host name/address mismatch: %s != %s",
  1384. X           inet_ntoa(addr), hp->h_name);
  1385. X    return (BAD);
  1386. X    }
  1387. X}
  1388. X
  1389. X#ifdef TEST
  1390. X
  1391. X/* Code for stand-alone testing. */
  1392. X
  1393. Xmain(argc, argv)
  1394. Xint     argc;
  1395. Xchar  **argv;
  1396. X{
  1397. X    struct from_host from;
  1398. X
  1399. X#ifdef LOG_MAIL
  1400. X    (void) openlog(argv[0], LOG_PID, FACILITY);
  1401. X#else
  1402. X    (void) openlog(argv[0], LOG_PID);
  1403. X#endif
  1404. X    (void) fromhost(&from);
  1405. X    printf("%s\n", hosts_info(&from));
  1406. X    return (0);
  1407. X}
  1408. X
  1409. X#endif
  1410. END_OF_fromhost.c
  1411. if test 8144 -ne `wc -c <fromhost.c`; then
  1412.     echo shar: \"fromhost.c\" unpacked with wrong size!
  1413. fi
  1414. # end of overwriting check
  1415. fi
  1416. if test -f hosts_access.c -a "${1}" != "-c" ; then 
  1417.   echo shar: Will not over-write existing file \"hosts_access.c\"
  1418. else
  1419. echo shar: Extracting \"hosts_access.c\" \(11173 characters\)
  1420. sed "s/^X//" >hosts_access.c <<'END_OF_hosts_access.c'
  1421. X /*
  1422. X  * This module implements a simple access control language that is based on
  1423. X  * host (or domain) names, netgroup, internet addresses (or network numbers)
  1424. X  * and daemon process names. When a match is found an optional shell command
  1425. X  * is executed and the search is terminated.
  1426. X  * 
  1427. X  * Diagnostics are reported through syslog(3).
  1428. X  * 
  1429. X  * Compile with -DNETGROUP if your library provides support for netgroups.
  1430. X  * 
  1431. X  * Compile with -DUSER_AT_HOST for rule-driven username lookups.
  1432. X  * 
  1433. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  1434. X  */
  1435. X
  1436. X#ifndef lint
  1437. Xstatic char sccsid[] = "@(#) hosts_access.c 1.10 93/03/07 22:47:36";
  1438. X#endif
  1439. X
  1440. X /* System libraries. */
  1441. X
  1442. X#include <sys/types.h>
  1443. X#include <sys/param.h>
  1444. X#include <netinet/in.h>
  1445. X#include <arpa/inet.h>
  1446. X#include <stdio.h>
  1447. X#include <syslog.h>
  1448. X#include <ctype.h>
  1449. X#include <errno.h>
  1450. X
  1451. Xextern char *fgets();
  1452. Xextern char *strchr();
  1453. Xextern char *strtok();
  1454. X
  1455. X#ifndef    INADDR_NONE
  1456. X#define    INADDR_NONE    (-1)        /* XXX should be 0xffffffff */
  1457. X#endif
  1458. X
  1459. X/* Local stuff. */
  1460. X
  1461. X#include "log_tcp.h"
  1462. X
  1463. X#ifdef INET_ADDR_BUG
  1464. X#include "inet_addr_fix"
  1465. X#endif
  1466. X
  1467. X/* Delimiters for lists of daemons or clients. */
  1468. X
  1469. Xstatic char sep[] = ", \t";
  1470. X
  1471. X/* Constants to be used in assignments only, not in comparisons... */
  1472. X
  1473. X#define    YES        1
  1474. X#define    NO        0
  1475. X#define    FAIL        (-1)
  1476. X
  1477. X/* Forward declarations. */
  1478. X
  1479. Xstatic int table_match();
  1480. Xstatic int list_match();
  1481. Xstatic int client_match();
  1482. Xstatic int string_match();
  1483. Xstatic int masked_match();
  1484. Xstatic char *xgets();
  1485. X
  1486. X/* The user@host access control. Trivial to add but complicates use. */
  1487. X
  1488. X#ifdef USER_AT_HOST
  1489. Xstatic int userhost_match();
  1490. X#define CLIENT_MATCH userhost_match
  1491. X#else
  1492. X#define CLIENT_MATCH client_match
  1493. X#endif
  1494. X
  1495. X/* Size of logical line buffer. */
  1496. X
  1497. X#define    BUFLEN 2048
  1498. X
  1499. X/* hosts_access - host access control facility */
  1500. X
  1501. Xint     hosts_access(daemon, client)
  1502. Xchar   *daemon;
  1503. Xstruct from_host *client;        /* host or user name may be empty */
  1504. X{
  1505. X
  1506. X    /*
  1507. X     * If the (daemon, client) pair is matched by an entry in the file
  1508. X     * /etc/hosts.allow, access is granted. Otherwise, if the (daemon,
  1509. X     * client) pair is matched by an entry in the file /etc/hosts.deny,
  1510. X     * access is denied. Otherwise, access is granted. A non-existent
  1511. X     * access-control file is treated as an empty file.
  1512. X     */
  1513. X
  1514. X    if (table_match(HOSTS_ALLOW, daemon, client))
  1515. X    return (YES);
  1516. X    if (table_match(HOSTS_DENY, daemon, client))
  1517. X    return (NO);
  1518. X    return (YES);
  1519. X}
  1520. X
  1521. X/* table_match - match table entries with (daemon, client) pair */
  1522. X
  1523. Xstatic int table_match(table, daemon, client)
  1524. Xchar   *table;
  1525. Xchar   *daemon;
  1526. Xstruct from_host *client;        /* host or user name may be empty */
  1527. X{
  1528. X    FILE   *fp;
  1529. X    char    sv_list[BUFLEN];        /* becomes list of daemons */
  1530. X    char   *cl_list;            /* becomes list of clients */
  1531. X    char   *sh_cmd;            /* becomes optional shell command */
  1532. X    int     match;
  1533. X    int     end;
  1534. X
  1535. X    /* The following variables should always be tested together. */
  1536. X
  1537. X    int     sv_match = NO;        /* daemon matched */
  1538. X    int     cl_match = NO;        /* client matced */
  1539. X
  1540. X    /*
  1541. X     * Process the table one logical line at a time. Lines that begin with a
  1542. X     * '#' character are ignored. Non-comment lines are broken at the ':'
  1543. X     * character (we complain if there is none). The first field is matched
  1544. X     * against the daemon process name (argv[0]), the second field against
  1545. X     * the host name or address. A non-existing table is treated as if it
  1546. X     * were an empty table. The search terminates at the first matching rule.
  1547. X     * When a match is found an optional shell command is executed.
  1548. X     */
  1549. X
  1550. X    if (fp = fopen(table, "r")) {
  1551. X    while (!(sv_match && cl_match) && xgets(sv_list, sizeof(sv_list), fp)) {
  1552. X        if (sv_list[end = strlen(sv_list) - 1] != '\n') {
  1553. X        syslog(LOG_ERR, "%s: missing newline or line too long", table);
  1554. X        continue;
  1555. X        }
  1556. X        if (sv_list[0] == '#')        /* skip comments */
  1557. X        continue;
  1558. X        while (end > 0 && isspace(sv_list[end - 1]))
  1559. X         end--;
  1560. X        sv_list[end] = '\0';        /* strip trailing whitespace */
  1561. X        if (sv_list[0] == 0)        /* skip blank lines */
  1562. X        continue;
  1563. X        if ((cl_list = strchr(sv_list, ':')) == 0) {
  1564. X        syslog(LOG_ERR, "%s: malformed entry: \"%s\"", table, sv_list);
  1565. X        continue;
  1566. X        }
  1567. X        *cl_list++ = '\0';            /* split 1st and 2nd fields */
  1568. X        if ((sh_cmd = strchr(cl_list, ':')) != 0)
  1569. X        *sh_cmd++ = '\0';        /* split 2nd and 3rd fields */
  1570. X        if ((sv_match = list_match(sv_list, daemon, string_match)))
  1571. X        cl_match = list_match(cl_list, (char *) client, CLIENT_MATCH);
  1572. X    }
  1573. X    (void) fclose(fp);
  1574. X    } else if (errno != ENOENT) {
  1575. X    syslog(LOG_ERR, "cannot open %s: %m", table);
  1576. X    }
  1577. X    match = (sv_match == YES && cl_match == YES);
  1578. X    if (match && sh_cmd)
  1579. X    OPTIONS_STYLE(sh_cmd, daemon, client);
  1580. X    return (match);
  1581. X}
  1582. X
  1583. X/* list_match - match an item against a list of tokens with exceptions */
  1584. X
  1585. Xstatic int list_match(list, item, match_fn)
  1586. Xchar   *list;
  1587. Xchar   *item;
  1588. Xint   (*match_fn) ();
  1589. X{
  1590. X    char   *tok;
  1591. X    int     match = NO;
  1592. X
  1593. X    /*
  1594. X     * Process tokens one at a time. We have exhausted all possible matches
  1595. X     * when we reach an "EXCEPT" token or the end of the list. If we do find
  1596. X     * a match, look for an "EXCEPT" list and recurse to determine whether
  1597. X     * the match is affected by any exceptions.
  1598. X     */
  1599. X
  1600. X    for (tok = strtok(list, sep); tok != 0; tok = strtok((char *) 0, sep)) {
  1601. X    if (strcasecmp(tok, "EXCEPT") == 0)    /* EXCEPT: give up */
  1602. X        break;
  1603. X    if (match = (*match_fn) (tok, item))    /* YES or FAIL */
  1604. X        break;
  1605. X    }
  1606. X    /* Process exceptions to YES or FAIL matches. */
  1607. X
  1608. X    if (match != NO) {
  1609. X    while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT"))
  1610. X         /* VOID */ ;
  1611. X    if (tok == 0 || list_match((char *) 0, item, match_fn) == NO)
  1612. X        return (match);
  1613. X    }
  1614. X    return (NO);
  1615. X}
  1616. X
  1617. X/* client_match - match host name and address against token */
  1618. X
  1619. Xstatic int client_match(tok, item)
  1620. Xchar   *tok;
  1621. Xchar   *item;
  1622. X{
  1623. X    struct from_host *client = (struct from_host *) item;
  1624. X    int     match;
  1625. X
  1626. X    /*
  1627. X     * Try to match the address first. If that fails, try to match the host
  1628. X     * name if available.
  1629. X     */
  1630. X
  1631. X    if ((match = string_match(tok, client->addr)) == 0)
  1632. X    if (client->name[0] != 0)
  1633. X        match = string_match(tok, client->name);
  1634. X    return (match);
  1635. X}
  1636. X
  1637. X#ifdef USER_AT_HOST
  1638. X
  1639. X/* userhost_match - do user@host access control */
  1640. X
  1641. Xstatic int userhost_match(tok, item)
  1642. Xchar   *tok;
  1643. Xchar   *item;
  1644. X{
  1645. X    struct from_host *client = (struct from_host *) item;
  1646. X    int     match = NO;
  1647. X    char   *at;
  1648. X    int     host_match;
  1649. X    int     user_match;
  1650. X
  1651. X    /*
  1652. X     * Warning: experimental code, enabled only when USER_AT_HOST is defined.
  1653. X     * 
  1654. X     * Basically, you specify user_pattern@host_pattern where remote username
  1655. X     * lookups are desired, and plain host_pattern for all other cases. The
  1656. X     * syntax of user name patterns is the same as for hosts or daemons, but
  1657. X     * ALL is probably the only user_pattern that makes sense.
  1658. X     * 
  1659. X     * In case of UDP connections, the result of username lookup will always be
  1660. X     * "unknown".
  1661. X     * 
  1662. X     * Return FAIL if we match a pattern of the form user@FAIL or FAIL@host:
  1663. X     * FAIL, like NO, is transitive. According to some people, such patterns
  1664. X     * should be taken out and shot. Good news: FAIL is on its way out.
  1665. X     */
  1666. X
  1667. X    if (at = strchr(tok + 1, '@')) {        /* user@host */
  1668. X    *at = 0;
  1669. X    if (host_match = client_match(at + 1, item)) {
  1670. X        if (client->user[0] == 0) {
  1671. X        if (client->sock_type != FROM_CONNECTED) {
  1672. X            client->user = FROM_UNKNOWN;
  1673. X        } else if (client->sin == 0) {
  1674. X            syslog(LOG_ERR, "no socket info for user name lookup");
  1675. X            client->user = FROM_UNKNOWN;
  1676. X        } else {
  1677. X            client->user = rfc931_name(client->sin);
  1678. X        }
  1679. X        }
  1680. X        user_match = string_match(tok, client->user);
  1681. X        if (user_match == NO || user_match == FAIL) {
  1682. X        match = user_match;
  1683. X        } else {
  1684. X        match = host_match;
  1685. X        }
  1686. X    }
  1687. X    *at = '@';
  1688. X    } else {                    /* host */
  1689. X    match = client_match(tok, item);
  1690. X    }
  1691. X    return (match);
  1692. X}
  1693. X
  1694. X#endif /* USER_AT_HOST */
  1695. X
  1696. X/* string_match - match string against token */
  1697. X
  1698. Xstatic int string_match(tok, string)
  1699. Xchar   *tok;
  1700. Xchar   *string;
  1701. X{
  1702. X    int     tok_len;
  1703. X    int     str_len;
  1704. X    char   *cut;
  1705. X#ifdef    NETGROUP
  1706. X    static char *mydomain = 0;
  1707. X#endif
  1708. X
  1709. X    /*
  1710. X     * Return YES if a token has the magic value "ALL". Return FAIL if the
  1711. X     * token is "FAIL". If the token starts with a "." (domain name), return
  1712. X     * YES if it matches the last fields of the string. If the token has the
  1713. X     * magic value "LOCAL", return YES if the string does not contain a "."
  1714. X     * character. If the token ends on a "." (network number), return YES if
  1715. X     * it matches the first fields of the string. If the token begins with a
  1716. X     * "@" (netgroup name), return YES if the string is a (host) member of
  1717. X     * the netgroup. Return YES if the token fully matches the string. If the
  1718. X     * token is a netnumber/netmask pair, return YES if the address is a
  1719. X     * member of the specified subnet.
  1720. X     */
  1721. X
  1722. X    if (tok[0] == '.') {            /* domain: match last fields */
  1723. X    if ((str_len = strlen(string)) > (tok_len = strlen(tok))
  1724. X        && strcasecmp(tok, string + str_len - tok_len) == 0)
  1725. X        return (YES);
  1726. X    } else if (tok[0] == '@') {            /* netgroup: look it up */
  1727. X#ifdef    NETGROUP
  1728. X    if (mydomain == 0)
  1729. X        yp_get_default_domain(&mydomain);
  1730. X    if (!isdigit(string[0])
  1731. X        && innetgr(tok + 1, string, (char *) 0, mydomain))
  1732. X        return (YES);
  1733. X#else
  1734. X    syslog(LOG_ERR, "wrapper: netgroup support is not configured");
  1735. X    return (NO);
  1736. X#endif
  1737. X    } else if (strcasecmp(tok, "ALL") == 0) {    /* all: match any */
  1738. X    return (YES);
  1739. X    } else if (strcasecmp(tok, "FAIL") == 0) {    /* fail: match any */
  1740. X    return (FAIL);
  1741. X    } else if (strcasecmp(tok, "LOCAL") == 0) {    /* local: no dots */
  1742. X    if (strchr(string, '.') == 0 && strcasecmp(string, "unknown") != 0)
  1743. X        return (YES);
  1744. X    } else if (!strcasecmp(tok, string)) {    /* match host name or address */
  1745. X    return (YES);
  1746. X    } else if (tok[(tok_len = strlen(tok)) - 1] == '.') {    /* network */
  1747. X    if (strncmp(tok, string, tok_len) == 0)
  1748. X        return (YES);
  1749. X    } else if ((cut = strchr(tok, '/')) != 0) {    /* netnumber/netmask */
  1750. X    if (isdigit(string[0]) && masked_match(tok, cut, string))
  1751. X        return (YES);
  1752. X    }
  1753. X    return (NO);
  1754. X}
  1755. X
  1756. X/* masked_match - match address against netnumber/netmask */
  1757. X
  1758. Xstatic int masked_match(tok, slash, string)
  1759. Xchar   *tok;
  1760. Xchar   *slash;
  1761. Xchar   *string;
  1762. X{
  1763. X    unsigned long net;
  1764. X    unsigned long mask;
  1765. X    unsigned long addr;
  1766. X
  1767. X    if ((addr = inet_addr(string)) == INADDR_NONE)
  1768. X    return (NO);
  1769. X    *slash = 0;
  1770. X    net = inet_addr(tok);
  1771. X    *slash = '/';
  1772. X    if (net == INADDR_NONE || (mask = inet_addr(slash + 1)) == INADDR_NONE) {
  1773. X    syslog(LOG_ERR, "bad net/mask access control: %s", tok);
  1774. X    return (NO);
  1775. X    }
  1776. X    return ((addr & mask) == net);
  1777. X}
  1778. X
  1779. X/* xgets - fgets() with backslash-newline stripping */
  1780. X
  1781. Xstatic char *xgets(buf, len, fp)
  1782. Xchar   *buf;
  1783. Xint     len;
  1784. XFILE   *fp;
  1785. X{
  1786. X    int     got;
  1787. X    char   *start = buf;
  1788. X
  1789. X    for (;;) {
  1790. X    if (fgets(buf, len, fp) == 0)
  1791. X        return (buf > start ? start : 0);
  1792. X    got = strlen(buf);
  1793. X    if (got >= 2 && buf[got - 2] == '\\' && buf[got - 1] == '\n') {
  1794. X        got -= 2;
  1795. X        buf += got;
  1796. X        len -= got;
  1797. X        buf[0] = 0;
  1798. X    } else {
  1799. X        return (start);
  1800. X    }
  1801. X    }
  1802. X}
  1803. END_OF_hosts_access.c
  1804. if test 11173 -ne `wc -c <hosts_access.c`; then
  1805.     echo shar: \"hosts_access.c\" unpacked with wrong size!
  1806. fi
  1807. # end of overwriting check
  1808. fi
  1809. if test -f shell_cmd.c -a "${1}" != "-c" ; then 
  1810.   echo shar: Will not over-write existing file \"shell_cmd.c\"
  1811. else
  1812. echo shar: Extracting \"shell_cmd.c\" \(2883 characters\)
  1813. sed "s/^X//" >shell_cmd.c <<'END_OF_shell_cmd.c'
  1814. X /*
  1815. X  * shell_cmd() takes a shell command template and performs %a (host
  1816. X  * address), %c (client info), %h (host name or address), %d (daemon name),
  1817. X  * %p (process id) and %u (user name) substitutions. The result is executed
  1818. X  * by a /bin/sh child process, with standard input, standard output and
  1819. X  * standard error connected to /dev/null.
  1820. X  * 
  1821. X  * Diagnostics are reported through syslog(3).
  1822. X  * 
  1823. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  1824. X  */
  1825. X
  1826. X#ifndef lint
  1827. Xstatic char sccsid[] = "@(#) shell_cmd.c 1.3 93/03/07 22:47:39";
  1828. X#endif
  1829. X
  1830. X/* System libraries. */
  1831. X
  1832. X#include <sys/types.h>
  1833. X#include <sys/param.h>
  1834. X#include <signal.h>
  1835. X#include <stdio.h>
  1836. X#include <syslog.h>
  1837. X
  1838. Xextern char *strncpy();
  1839. Xextern void closelog();
  1840. Xextern void exit();
  1841. X
  1842. X/* Local stuff. */
  1843. X
  1844. X#include "log_tcp.h"
  1845. X
  1846. X/* Forward declarations. */
  1847. X
  1848. Xstatic void do_child();
  1849. X
  1850. X/* shell_cmd - expand %<char> sequences and execute shell command */
  1851. X
  1852. Xvoid    shell_cmd(string, daemon, client)
  1853. Xchar   *string;
  1854. Xchar   *daemon;
  1855. Xstruct from_host *client;
  1856. X{
  1857. X    char    cmd[BUFSIZ];
  1858. X    int     child_pid;
  1859. X    int     wait_pid;
  1860. X    int     daemon_pid = getpid();
  1861. X
  1862. X    /*
  1863. X     * Most of the work is done within the child process, to minimize the
  1864. X     * risk of damage to the parent.
  1865. X     */
  1866. X
  1867. X    switch (child_pid = fork()) {
  1868. X    case -1:                    /* error */
  1869. X    syslog(LOG_ERR, "fork: %m");
  1870. X    break;
  1871. X    case 00:                    /* child */
  1872. X    percent_x(cmd, sizeof(cmd), string, daemon, client, daemon_pid);
  1873. X    do_child(daemon, cmd);
  1874. X    /* NOTREACHED */
  1875. X    default:                    /* parent */
  1876. X    while ((wait_pid = wait((int *) 0)) != -1 && wait_pid != child_pid)
  1877. X         /* void */ ;
  1878. X    }
  1879. X}
  1880. X
  1881. X/* do_child - exec command with { stdin, stdout, stderr } to /dev/null */
  1882. X
  1883. Xstatic void do_child(myname, command)
  1884. Xchar   *myname;
  1885. Xchar   *command;
  1886. X{
  1887. X    char   *error = 0;
  1888. X    int     tmp_fd;
  1889. X
  1890. X    /*
  1891. X     * SunOS 4.x may send a SIGHUP to grandchildren if the child exits first.
  1892. X     * Sessions and process groups make old and grown-up programmers tear out
  1893. X     * what little hair is left and run away crying.
  1894. X     */
  1895. X
  1896. X    signal(SIGHUP, SIG_IGN);
  1897. X
  1898. X    /*
  1899. X     * Close a bunch of file descriptors. The Ultrix inetd only passes stdin,
  1900. X     * but other inetd implementations set up stdout as well. Ignore errors.
  1901. X     */
  1902. X
  1903. X    closelog();
  1904. X    for (tmp_fd = 0; tmp_fd < 10; tmp_fd++)
  1905. X    (void) close(tmp_fd);
  1906. X
  1907. X    /* Set up new stdin, stdout, stderr, and exec the shell command. */
  1908. X
  1909. X    if (open("/dev/null", 2) != 0) {
  1910. X    error = "open /dev/null: %m";
  1911. X    } else if (dup(0) != 1 || dup(0) != 2) {
  1912. X    error = "dup: %m";
  1913. X    } else {
  1914. X    (void) execl("/bin/sh", "sh", "-c", command, (char *) 0);
  1915. X    error = "execl /bin/sh: %m";
  1916. X    }
  1917. X
  1918. X    /* We can reach the following code only if there was an error. */
  1919. X
  1920. X#ifdef LOG_MAIL
  1921. X    (void) openlog(myname, LOG_PID, FACILITY);
  1922. X#else
  1923. X    (void) openlog(myname, LOG_PID);
  1924. X#endif
  1925. X    syslog(LOG_ERR, error);
  1926. X    exit(0);
  1927. X}
  1928. END_OF_shell_cmd.c
  1929. if test 2883 -ne `wc -c <shell_cmd.c`; then
  1930.     echo shar: \"shell_cmd.c\" unpacked with wrong size!
  1931. fi
  1932. # end of overwriting check
  1933. fi
  1934. if test -f log_tcp.h -a "${1}" != "-c" ; then 
  1935.   echo shar: Will not over-write existing file \"log_tcp.h\"
  1936. else
  1937. echo shar: Extracting \"log_tcp.h\" \(1448 characters\)
  1938. sed "s/^X//" >log_tcp.h <<'END_OF_log_tcp.h'
  1939. X/* @(#) log_tcp.h 1.3 93/03/07 22:47:41 */
  1940. X
  1941. X/* Location of the access control files. */
  1942. X
  1943. X#ifndef HOSTS_ALLOW
  1944. X#define HOSTS_ALLOW    "/etc/hosts.allow"
  1945. X#endif
  1946. X
  1947. X#ifndef HOSTS_DENY
  1948. X#define HOSTS_DENY    "/etc/hosts.deny"
  1949. X#endif
  1950. X
  1951. X /* Structure filled in by the fromhost() routine. */
  1952. X
  1953. Xstruct from_host {
  1954. X    int     sock_type;            /* socket type, see below */
  1955. X    char   *name;            /* host name */
  1956. X    char   *addr;            /* host address */
  1957. X    char   *user;            /* user name */
  1958. X    struct sockaddr_in *sin;        /* their side of the link */
  1959. X};
  1960. X
  1961. X#define FROM_UNKNOWN    "unknown"    /* name or address lookup failed */
  1962. X#define FROM_HOST(f) \
  1963. X    (((f)->name[0] && strcmp((f)->name, FROM_UNKNOWN)) ? (f)->name : (f)->addr)
  1964. X
  1965. X#define FROM_ADDRLEN    (4*3+3+1)    /* string with IP address */
  1966. X
  1967. X/* Socket types: 0 means unknown. */
  1968. X
  1969. X#define FROM_CONNECTED        1    /* connection-oriented */
  1970. X#define FROM_UNCONNECTED    2    /* non connection-oriented */
  1971. X
  1972. X/* Global functions. */
  1973. X
  1974. Xextern int fromhost();            /* get/validate remote host info */
  1975. Xextern int hosts_access();        /* access control */
  1976. Xextern void refuse();            /* refuse request */
  1977. Xextern void shell_cmd();        /* execute shell command */
  1978. Xextern void percent_x();        /* do %<char> expansion */
  1979. Xextern char *rfc931_name();        /* remote name from RFC 931 daemon */
  1980. Xextern char *hosts_info();        /* show origin of connection */
  1981. Xextern void clean_exit();        /* clean up and exit */
  1982. X
  1983. X/* Global variables. */
  1984. X
  1985. Xextern int log_severity;        /* for connection logging */
  1986. END_OF_log_tcp.h
  1987. if test 1448 -ne `wc -c <log_tcp.h`; then
  1988.     echo shar: \"log_tcp.h\" unpacked with wrong size!
  1989. fi
  1990. # end of overwriting check
  1991. fi
  1992. if test -f try.c -a "${1}" != "-c" ; then 
  1993.   echo shar: Will not over-write existing file \"try.c\"
  1994. else
  1995. echo shar: Extracting \"try.c\" \(3200 characters\)
  1996. sed "s/^X//" >try.c <<'END_OF_try.c'
  1997. X /*
  1998. X  * try - program to try out host access-control tables, including the
  1999. X  * optional shell commands.
  2000. X  * 
  2001. X  * usage: try process_name host_name_or_address
  2002. X  * 
  2003. X  * where process_name is a daemon process name (argv[0] value). If a host name
  2004. X  * is specified, both the name and address will be used to check the address
  2005. X  * control tables. If a host address is specified, the program pretends that
  2006. X  * host name lookup failed.
  2007. X  * 
  2008. X  * Most errors will be reported to the syslog daemon, so you'd better keep a
  2009. X  * tail on the logfile.
  2010. X  */
  2011. X
  2012. X#ifndef lint
  2013. Xstatic char sccsid[] = "@(#) try.c 1.3 93/03/07 22:47:43";
  2014. X#endif
  2015. X
  2016. X#include <sys/types.h>
  2017. X#include <netinet/in.h>
  2018. X#include <arpa/inet.h>
  2019. X#include <netdb.h>
  2020. X#include <stdio.h>
  2021. X#include <syslog.h>
  2022. X
  2023. X#ifdef HOSTS_ACCESS
  2024. X
  2025. X#ifndef    INADDR_NONE
  2026. X#define    INADDR_NONE    (-1)        /* XXX should be 0xffffffff */
  2027. X#endif
  2028. X
  2029. X#include "log_tcp.h"
  2030. X
  2031. X#ifdef INET_ADDR_BUG
  2032. X#include "inet_addr_fix"
  2033. X#endif
  2034. X
  2035. Xint     log_severity = SEVERITY;    /* run-time adjustable */
  2036. X
  2037. X/* Try out a (daemon,client) pair */
  2038. X
  2039. Xtry(daemon, name, addr)
  2040. Xchar   *daemon;
  2041. Xchar   *name;
  2042. Xchar   *addr;
  2043. X{
  2044. X    printf(" Daemon:   %s\n", daemon);
  2045. X    printf(" Hostname: %s\n", name);
  2046. X    printf(" Address:  %s\n", addr);
  2047. X    printf(" Access:   %s\n",
  2048. X       hosts_ctl(daemon, name, addr, "you") ? "granted" : "denied");
  2049. X}
  2050. X
  2051. X/* function to intercept the real shell_cmd() */
  2052. X
  2053. Xvoid    shell_cmd(cmd, daemon, client)
  2054. Xchar   *cmd;
  2055. Xchar   *daemon;
  2056. Xstruct from_host *client;
  2057. X{
  2058. X    char    buf[BUFSIZ];
  2059. X    int     pid = getpid();
  2060. X
  2061. X    percent_x(buf, sizeof(buf), cmd, daemon, client, pid);
  2062. X    printf(" Command:  %s\n", buf);
  2063. X}
  2064. X
  2065. X/* function to intercept the real process_options() */
  2066. X
  2067. Xprocess_options(options, daemon, client)
  2068. Xchar   *options;
  2069. Xchar   *daemon;
  2070. Xstruct from_host *client;
  2071. X{
  2072. X    char    buf[BUFSIZ];
  2073. X    int     pid = getpid();
  2074. X
  2075. X    percent_x(buf, sizeof(buf), options, daemon, client, pid);
  2076. X    printf(" Options:  %s\n", buf);
  2077. X}
  2078. X
  2079. Xmain(argc, argv)
  2080. Xint     argc;
  2081. Xchar  **argv;
  2082. X{
  2083. X    struct hostent *hp;
  2084. X
  2085. X#ifdef LOG_MAIL
  2086. X    openlog(argv[0], LOG_PID, FACILITY);
  2087. X#else
  2088. X    openlog(argv[0], LOG_PID);
  2089. X#endif
  2090. X
  2091. X    /*
  2092. X     * Abuse inet_addr() to find out if a host name or address was specified.
  2093. X     * 
  2094. X     * If a host address is specified, pretend that the host name lookup failed.
  2095. X     * This allows us to simulate the effect of host name lookup failures.
  2096. X     * 
  2097. X     * If a host name is specified, insist that the address is known. The reason
  2098. X     * for giving up is that in real life, a host address is always
  2099. X     * available.
  2100. X     */
  2101. X
  2102. X    if (argc != 3) {
  2103. X    fprintf(stderr, "usage: %s process_name host_name_or_address\n",
  2104. X        argv[0]);
  2105. X    return (1);
  2106. X    }
  2107. X    if (inet_addr(argv[2]) != INADDR_NONE) {    /* address specified */
  2108. X    try(argv[1], FROM_UNKNOWN, argv[2]);
  2109. X    return (0);
  2110. X    }
  2111. X    if ((hp = gethostbyname(argv[2])) == 0) {    /* address lookup fails */
  2112. X    fprintf(stderr, "host %s: address lookup failed\n", argv[2]);
  2113. X    return (1);
  2114. X    }
  2115. X    while (hp->h_addr_list[0])            /* name and address known */
  2116. X    try(argv[1], hp->h_name,
  2117. X        inet_ntoa(*(struct in_addr *) * hp->h_addr_list++));
  2118. X    return (0);
  2119. X}
  2120. X
  2121. X#else
  2122. X
  2123. Xmain()
  2124. X{
  2125. X    fprintf(stderr, "host access control is not enabled.\n");
  2126. X    return (1);
  2127. X}
  2128. X
  2129. X#endif
  2130. END_OF_try.c
  2131. if test 3200 -ne `wc -c <try.c`; then
  2132.     echo shar: \"try.c\" unpacked with wrong size!
  2133. fi
  2134. # end of overwriting check
  2135. fi
  2136. if test -f refuse.c -a "${1}" != "-c" ; then 
  2137.   echo shar: Will not over-write existing file \"refuse.c\"
  2138. else
  2139. echo shar: Extracting \"refuse.c\" \(737 characters\)
  2140. sed "s/^X//" >refuse.c <<'END_OF_refuse.c'
  2141. X /*
  2142. X  * refuse() reports a refused connection, and takes the consequences: in
  2143. X  * case of a datagram-oriented service, the unread datagram is taken from
  2144. X  * the input queue (or inetd would see the same datagram again and again);
  2145. X  * the program is terminated.
  2146. X  * 
  2147. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  2148. X  */
  2149. X
  2150. X#ifndef lint
  2151. Xstatic char sccsid[] = "@(#) refuse.c 1.2 92/06/11 22:21:34";
  2152. X#endif
  2153. X
  2154. X/* System libraries. */
  2155. X
  2156. X#include <syslog.h>
  2157. X
  2158. X/* Local stuff. */
  2159. X
  2160. X#include "log_tcp.h"
  2161. X
  2162. X/* refuse - refuse request from bad host */
  2163. X
  2164. Xvoid    refuse(client)
  2165. Xstruct from_host *client;
  2166. X{
  2167. X    syslog(LOG_WARNING, "refused connect from %s", hosts_info(client));
  2168. X    clean_exit(client);
  2169. X    /* NOTREACHED */
  2170. X}
  2171. END_OF_refuse.c
  2172. if test 737 -ne `wc -c <refuse.c`; then
  2173.     echo shar: \"refuse.c\" unpacked with wrong size!
  2174. fi
  2175. # end of overwriting check
  2176. fi
  2177. if test -f Makefile.dist -a "${1}" != "-c" ; then 
  2178.   echo shar: Will not over-write existing file \"Makefile.dist\"
  2179. else
  2180. echo shar: Extracting \"Makefile.dist\" \(15575 characters\)
  2181. sed "s/^X//" >Makefile.dist <<'END_OF_Makefile.dist'
  2182. X# @(#) Makefile.dist 1.2 93/03/24 22:42:41
  2183. X# 
  2184. X# If you did not already do so, copy the file Makefile.dist to Makefile
  2185. X# and edit the copy, not the original. Have a copy of the README file at
  2186. X# hand while editing. It gives some additional background.
  2187. X#
  2188. X# For your convenience, all configurable parameters have been moved into
  2189. X# the Makefile, so that you do not have to hack the source files anymore.
  2190. X#
  2191. X# Some parameters must always be set to match the operating environment.
  2192. X# Other parameter settings are a matter of taste. Their sections headings
  2193. X# are labeled "(Optional)". The defaults correspond to the programs as
  2194. X# documented in the manual pages.
  2195. X
  2196. X######################################################
  2197. X# Choice between easy and advanced installation recipe
  2198. X# 
  2199. X# According to the easy installation recipe in the README file, vendor-
  2200. X# provided network daemons are moved to "some other" directory, and the
  2201. X# tcpd wrapper fills in the "holes". For this mode of operation, the
  2202. X# REAL_DAEMON_DIR macro should be set to the "some other" directory.
  2203. X# Uncomment the appropriate line. The "..." is here for historical
  2204. X# reasons only; you will probably want to use some other name. Watch out
  2205. X# for the quotes and backslashes.
  2206. X
  2207. XREAL_DAEMON_DIR=\"/usr/etc/...\"    # BSD 4.3 Ultrix 4.x SunOS 4.x
  2208. X#REAL_DAEMON_DIR=\"/usr/sbin/...\"    # SysV.4 Solaris 2.x
  2209. X#REAL_DAEMON_DIR=\"/usr/libexec/...\"    # BSD 4.4
  2210. X
  2211. X# According to the advanced installation recipe, vendor-provided daemons
  2212. X# are left alone, and the inetd file is edited instead. In that case, the
  2213. X# REAL_DAEMON_DIR macro should reflect the actual directory with (most of)
  2214. X# your vendor-provided network daemons.  Uncomment the appropriate line.
  2215. X
  2216. X#REAL_DAEMON_DIR=\"/usr/etc\"        # BSD 4.3 Ultrix 4.x SunOS 4.x
  2217. X#REAL_DAEMON_DIR=\"/usr/sbin\"        # SysV.4 Solaris 2.x
  2218. X#REAL_DAEMON_DIR=\"/usr/libexec\"    # BSD 4.4
  2219. X
  2220. X#########################################################
  2221. X# Differences between ranlib(1) and ar(1) implementations
  2222. X#
  2223. X# Some C compilers (Ultrix 4.x) insist that ranlib(1) be run on an object
  2224. X# library; some don't care as long as the modules are in the right order;
  2225. X# some systems don't even have a ranlib(1) command. SGI IRIX uses the 's'
  2226. X# option to the 'ar' command instead. Make your choice.
  2227. X
  2228. XRANLIB    = ranlib    # have ranlib (BSD-ish UNIX)
  2229. X#RANLIB    = echo        # no ranlib (SYSV-ish UNIX)
  2230. X
  2231. XARFLAGS    = rv        # OK for most systems
  2232. X#ARFLAGS= rvs        # ranlib flag for 'ar' on IRIX 4.0.x
  2233. X
  2234. X#######################################################
  2235. X# Routines that are not present in the system libraries
  2236. X# 
  2237. X# The strcasecmp.c file provided with this package comes from 4.3+BSD
  2238. X# UNIX. The setenv.c module is a re-implementation of the 4.4 BSD one.
  2239. X# strtok.c comes from 4.4BSD. 
  2240. X
  2241. XAUX_OBJ    = setenv.o            # no setenv(3)
  2242. X#AUX_OBJ= setenv.o strcasecmp.o        # no setenv(3) and no strcasecmp(3)
  2243. X#AUX_OBJ= setenv.o strcasecmp.o strtok.o
  2244. X
  2245. X# While building the file strcasecmp.o, the compiler may complain that
  2246. X# u_char is undefined. Uncomment the following definition for a fix.
  2247. X#
  2248. X#UCHAR    = -Du_char="unsigned char"    # no u_char type
  2249. X
  2250. X# Uncomment the following if your C library has index/rindex/bcmp
  2251. X# but does not provide the strchr/strrchr/memcmp routines. If that
  2252. X# is the case, you probably also do not have strtok() (see above).
  2253. X#
  2254. X#STRINGS= -Dindex=strchr -Drindex=strrchr -Dmemcmp=bcmp
  2255. X
  2256. X###########################################
  2257. X# Selection of non-default object libraries
  2258. X#
  2259. X# Many System-V versions require that you explicitly specify the networking
  2260. X# libraries (for example, -lnet or -linet).
  2261. X#
  2262. X#LIBS    = -lsocket -lnsl    # SysV.4 Solaris 2.x
  2263. X#LIBS    = -lsun            # IRIX
  2264. X
  2265. X#########################
  2266. X# Ultrix-specific section
  2267. X#
  2268. X# Ultrix users may want to use the miscd wrapper, too. The Ultrix miscd
  2269. X# implements among others the SYSTAT service which runs the WHO command,
  2270. X# and thus provides a subset of the finger service. The very first wrapper
  2271. X# application (in the early hours of May 20, 1990) was to monitor SYSTAT.
  2272. X
  2273. Xall:    tcpd try            # no Ultrix miscd
  2274. X#all:    tcpd try miscd            # Ultrix, monitor systat etc. too
  2275. X
  2276. X#REAL_MISCD=\"/usr/etc/.../miscd\"    # easy installation
  2277. X#REAL_MISCD=\"/usr/etc/miscd\"        # advanced installation
  2278. X
  2279. X################################
  2280. X# System-specific compiler flags
  2281. X#
  2282. X# Apollo Domain/OS offers both bsd and sys5 environments, sometimes
  2283. X# on the same machine.  If your Apollo is primarily sys5.3 and also
  2284. X# has bsd4.3, uncomment the following to build under bsd and run under
  2285. X# either environment.
  2286. X#
  2287. X#SYSTYPE= -A run,any -A sys,any
  2288. X
  2289. X# For MIPS RISC/os 4_52.p3, uncomment the following definition.
  2290. X#
  2291. X#SYSTYPE= -sysname bsd43
  2292. X
  2293. X############################
  2294. X# Working around system bugs
  2295. X#
  2296. X# Some versions of Apollo or SYSV.4 UNIX have a bug in the getpeername(2)
  2297. X# routine.  You may have this bug when the wrapper reports that all UDP
  2298. X# connections come from address 0.0.0.0. Compile with -DGETPEERNAME_BUG
  2299. X# for a workaround. The workaround does no harm on other systems. If in
  2300. X# doubt, leave it in.
  2301. X#
  2302. X# Some System V versions (Solaris 2) have a problem in the recvfrom()
  2303. X# emulation code.  You may have this bug when the wrapper programs
  2304. X# complain about "unexpected address family 0" when processing an UDP
  2305. X# request. Compile with -DRECVFROM_BUG for a workaround. The workaround
  2306. X# does no harm on other systems. If in doubt, leave it in.
  2307. X# 
  2308. X# With some System V implementations (SCO UNIX 3.2v4), even compiling
  2309. X# with -DRECVFROM_BUG does not solve the "address family 0" problem. If
  2310. X# that is the case, compile with -DADDRESS_FAMILY_BUG instead.
  2311. X#
  2312. X# DG/UX 5.4.1 comes with an inet_ntoa() function that returns a structure
  2313. X# instead of a long integer. Compile with -DINET_ADDR_BUG to work around
  2314. X# this mutant behavour.
  2315. X
  2316. XBUGS    = -DGETPEERNAME_BUG -DRECVFROM_BUG # -DADDRESS_FAMILY_BUG
  2317. X
  2318. X####################################################
  2319. X# Whether or not your system has NIS (or YP) support
  2320. X#
  2321. X# If your system supports NIS or YP-style netgroups, enable the following
  2322. X# macro definition. Netgroups are used only for host access control.
  2323. X#
  2324. X#NETGROUP= -DNETGROUP
  2325. X
  2326. X# End of the required configuration options; all other ones are optional.
  2327. X#########################################################################
  2328. X
  2329. X################################################################
  2330. X# Changing the default disposition of logfile records (Optional)
  2331. X#
  2332. X# By default, logfile entries are written to the same file as used for
  2333. X# sendmail transaction logs. See your /etc/syslog.conf file for actual
  2334. X# path names of logfiles. The tutorial section in the README file
  2335. X# gives a brief introduction to the syslog daemon.
  2336. X# 
  2337. X# Change the FACILITY definition below if you disagree with the default
  2338. X# disposition. Some syslog versions (including Ultrix 4.x) do not provide
  2339. X# this flexibility.
  2340. X# 
  2341. X# If nothing shows up on your system, it may be that the syslog records
  2342. X# are sent to a dedicated loghost. It may also be that no syslog daemon
  2343. X# is running at all. The README file gives pointers to surrogate syslog
  2344. X# implementations for systems that have no syslog library routines or
  2345. X# no syslog daemons.
  2346. X#
  2347. X# The LOG_XXX names below are taken from the /usr/include/syslog.h file.
  2348. X
  2349. XFACILITY= LOG_MAIL    # LOG_MAIL is what most sendmail daemons use
  2350. X
  2351. X# The syslog priority at which successful connections are logged.
  2352. X
  2353. XSEVERITY= LOG_INFO    # LOG_INFO is normally not logged to the console
  2354. X
  2355. X#############################################
  2356. X# Enabling remote username lookups (Optional)
  2357. X#
  2358. X# By default, the wrappers just report the remote host name (the host
  2359. X# address if the host name lookup fails or times out).  Username lookups
  2360. X# require that the remote host runs a daemon that supports a RFC 931 like
  2361. X# protocol.  Remote user name lookups are not possible for UDP-based
  2362. X# connections, and can cause noticeable delays with connections from
  2363. X# non-UNIX PCs.  On some systems, remote username lookups can trigger a
  2364. X# kernel bug, causing loss of service. The README file gives details on
  2365. X# how to find out if your system has that problem.
  2366. X# 
  2367. X# Uncomment the following definition if the wrappers should always
  2368. X# attempt to get the remote user name.
  2369. X#
  2370. X# The default username lookup timeout is 30 seconds.
  2371. X#
  2372. X#AUTH    = -DRFC931_TIMEOUT=30 -DRFC931
  2373. X
  2374. X# The USER_AT_HOST feature does selective username lookups. It triggers
  2375. X# on access control patterns of the form xxx@yyy. Until now, such
  2376. X# patterns were not used, so that USER_AT_HOST does not break existing
  2377. X# rules.
  2378. X# 
  2379. X# The feature is not documented and is not yet intended for general use,
  2380. X# because it can complicate the design of access control tables.
  2381. X# 
  2382. X# With USER_AT_HOST enabled, remote username lookups are done only for
  2383. X# user_pattern@host_pattern expressions in the access control files, but
  2384. X# only when the host_pattern matches. Example: "ALL: @pcgroup ALL@ALL"
  2385. X# avoids user name lookups for members of the pcgroup netgroup.  The
  2386. X# user_pattern syntax is identical to that of host_pattern, but "ALL"
  2387. X# is usually the only user_pattern that makes sense.
  2388. X# 
  2389. X# The default username lookup timeout is 30 seconds.
  2390. X#
  2391. X#AUTH    = -DRFC931_TIMEOUT=30 -DUSER_AT_HOST
  2392. X
  2393. X########################################################
  2394. X# Turning on experimental language extensions (Optional)
  2395. X#
  2396. X# Instead of the officially documented access control language, the
  2397. X# software can be configured to implement a more experimental language
  2398. X# that is easily extended. The experimental language is implemented by
  2399. X# the "options.c" source module which also serves as its documentation.
  2400. X
  2401. XSTYLE    = -DOPTIONS_STYLE=shell_cmd        # The documented language
  2402. X#STYLE    = -DOPTIONS_STYLE=process_options    # The experimental one
  2403. X
  2404. X######################################################
  2405. X# Changing the default file protection mask (Optional)
  2406. X#
  2407. X# On many systems, network daemons and other system processes are started
  2408. X# with a zero umask value, so that world-writable files may be produced.
  2409. X# It is a good idea to edit your /etc/rc* files so that they begin with
  2410. X# an explicit umask setting.  On our site we use `umask 022' because it
  2411. X# does not break anything yet gives adequate protection against tampering.
  2412. X# 
  2413. X# The following macro specifies the default umask for processes run under
  2414. X# control of the daemon wrappers. Comment it out only if you are certain
  2415. X# that inetd and its children are started with a safe umask value.
  2416. X
  2417. XUMASK    = -DDAEMON_UMASK=022
  2418. X
  2419. X#######################################
  2420. X# Turning off access control (Optional)
  2421. X#
  2422. X# By default, host access control is enabled.  To disable host access
  2423. X# control, comment out the following definition.  Host access control
  2424. X# can also be turned off at runtime by providing no or empty access
  2425. X# control tables.
  2426. X
  2427. XACCESS    = -DHOSTS_ACCESS
  2428. X
  2429. X########################################################
  2430. X# Changing the access control table pathnames (Optional)
  2431. X#
  2432. X# The HOSTS_ALLOW and HOSTS_DENY macros define where the programs will
  2433. X# look for access control information. Watch out for the quotes and
  2434. X# backslashes when you make changes.
  2435. X
  2436. XTABLES    = -DHOSTS_DENY=\"/etc/hosts.deny\" -DHOSTS_ALLOW=\"/etc/hosts.allow\"
  2437. X
  2438. X###########################################
  2439. X# Turning off host NAME checking (Optional)
  2440. X#
  2441. X# By default, the software tries to protect against hosts that claim to
  2442. X# have someone elses host name. This is relevant for network services
  2443. X# whose authentication depends on host names, such as rsh and rlogin.
  2444. X#
  2445. X# With paranoid mode on, connections will be rejected when the host name
  2446. X# does not match the host address. Connections will also be rejected when
  2447. X# the host name cannot be verified because gethostbyname() fails.
  2448. X#
  2449. X# Comment out the following definition if you do not need this additional
  2450. X# protection. If paranoid mode is off, and a host name check fails, the
  2451. X# daemon wrappers will use only the host address, but your daemons may
  2452. X# still use the host name.
  2453. X
  2454. XPARANOID= -DPARANOID
  2455. X
  2456. X#############################################
  2457. X# Turning on host ADDRESS checking (Optional)
  2458. X#
  2459. X# Optionally, the software tries to protect against hosts that pretend to
  2460. X# have someone elses host address. This is relevant for network services
  2461. X# whose authentication depends on host names, such as rsh and rlogin,
  2462. X# because the network address is used to look up the remote host name.
  2463. X# 
  2464. X# The protection is effective only when the offending host claims to have
  2465. X# a network address that lies outside its own network.
  2466. X#
  2467. X# My site has been running rlogind and rshd daemons that implement this
  2468. X# feature for more than 2 years, and without any ill effects.
  2469. X#
  2470. X# This feature cannot be used with SunOS 4.x because of a kernel bug in
  2471. X# the implementation of the getsockopt() system call. Kernel panics have
  2472. X# been reported for SunOS 4.1.1 and SunOS 4.1.2. Symptoms are "BAD TRAP"
  2473. X# and "Data fault" while executing the tcp_ctloutput() kernel function.
  2474. X#
  2475. X# Uncomment the following macro definition if your getsockopt() is OK.
  2476. X#
  2477. X# KILL_OPT= -DKILL_IP_OPTIONS
  2478. X
  2479. X## End configuration options
  2480. X############################
  2481. X
  2482. XCFLAGS    = -O -DFACILITY=$(FACILITY) $(ACCESS) $(PARANOID) $(NETGROUP) \
  2483. X    $(BUGS) $(SYSTYPE) $(AUTH) $(UMASK) -DREAL_MISCD=$(REAL_MISCD) \
  2484. X    -DREAL_DAEMON_DIR=$(REAL_DAEMON_DIR) $(STYLE) $(KILL_OPT) \
  2485. X    -DSEVERITY=$(SEVERITY) $(UCHAR) $(TABLES) $(STRINGS)
  2486. X
  2487. XLIB_OBJ= hosts_access.o options.o shell_cmd.o rfc931.o hosts_info.o \
  2488. X    hosts_ctl.o refuse.o percent_x.o clean_exit.o $(AUX_OBJ) \
  2489. X    fromhost.o fix_options.o
  2490. X
  2491. XKIT    = README miscd.c tcpd.c fromhost.c hosts_access.c shell_cmd.c \
  2492. X    log_tcp.h try.c refuse.c Makefile.dist hosts_access.5 strcasecmp.c \
  2493. X    BLURB rfc931.c tcpd.8 hosts_info.c hosts_access.3 hosts_ctl.c \
  2494. X    percent_x.c options.c clean_exit.c setenv.c patchlevel.h strtok.c \
  2495. X    fix_options.c inet_addr_fix
  2496. X
  2497. XLIB    = libwrap.a
  2498. X
  2499. X$(LIB):    $(LIB_OBJ)
  2500. X    rm -f $(LIB)
  2501. X    ar $(ARFLAGS) $(LIB) $(LIB_OBJ)
  2502. X    $(RANLIB) $(LIB)
  2503. X
  2504. Xtcpd:    tcpd.o fromhost.o $(LIB)
  2505. X    $(CC) $(CFLAGS) -o $@ tcpd.o fromhost.o $(LIB) $(LIBS)
  2506. X
  2507. Xmiscd:    miscd.o fromhost.o $(LIB)
  2508. X    $(CC) $(CFLAGS) -o $@ miscd.o fromhost.o $(LIB) $(LIBS)
  2509. X
  2510. Xtry:    try.o $(LIB)
  2511. X    $(CC) $(CFLAGS) -o $@ try.o $(LIB) $(LIBS)
  2512. X
  2513. Xfromhost: fromhost.c log_tcp.h Makefile $(LIB)
  2514. X    $(CC) $(CFLAGS) -DTEST -o fromhost fromhost.c $(LIB) $(LIBS)
  2515. X    rm -f fromhost.o
  2516. X
  2517. Xshar:    $(KIT)
  2518. X    @shar $(KIT)
  2519. X
  2520. Xkit:    $(KIT)
  2521. X    @makekit $(KIT)
  2522. X
  2523. Xarchive:
  2524. X    $(ARCHIVE) $(KIT)
  2525. X
  2526. Xclean:
  2527. X    rm -f tcpd miscd try fromhost *.[oa] core
  2528. X
  2529. X# Enable all bells and whistles for linting.
  2530. X
  2531. Xlint: tcpd_lint miscd_lint try_lint
  2532. X
  2533. Xtcpd_lint:
  2534. X    lint -DFACILITY=LOG_MAIL -DHOSTS_ACCESS -DPARANOID -DNETGROUP \
  2535. X    -DGETPEERNAME_BUG -DDAEMON_UMASK=022 -DSEVERITY=$(SEVERITY) \
  2536. X    -DUSER_AT_HOST -DKILL_IP_OPTIONS -DOPTIONS_STYLE=process_options \
  2537. X    tcpd.c fromhost.c hosts_access.c shell_cmd.c refuse.c rfc931.c \
  2538. X    hosts_info.c percent_x.c clean_exit.c options.c setenv.c fix_options.c
  2539. X
  2540. Xmiscd_lint:
  2541. X    lint -DFACILITY=LOG_MAIL -DHOSTS_ACCESS -DPARANOID -DNETGROUP \
  2542. X    -DGETPEERNAME_BUG -DDAEMON_UMASK=022 -DSEVERITY=$(SEVERITY) \
  2543. X    -DUSER_AT_HOST -DKILL_IP_OPTIONS -DOPTIONS_STYLE=process_options \
  2544. X    miscd.c fromhost.c hosts_access.c shell_cmd.c refuse.c rfc931.c \
  2545. X    hosts_info.c percent_x.c clean_exit.c options.c setenv.c fix_options.c
  2546. X
  2547. Xtry_lint:
  2548. X    lint -DFACILITY=LOG_MAIL -DHOSTS_ACCESS -DNETGROUP try.c \
  2549. X    hosts_ctl.c hosts_access.c hosts_info.c percent_x.c
  2550. X
  2551. X# Compilation dependencies.
  2552. X
  2553. Xclean_exit.o: log_tcp.h Makefile
  2554. Xfix_options.o: log_tcp.h Makefile
  2555. Xfromhost.o: log_tcp.h Makefile
  2556. Xhosts_access.o: log_tcp.h Makefile
  2557. Xhosts_ctl.o: log_tcp.h Makefile
  2558. Xhosts_info.o: log_tcp.h Makefile
  2559. Xmiscd.o: patchlevel.h log_tcp.h Makefile
  2560. Xoptions.o: log_tcp.h Makefile
  2561. Xpercent_x.o: log_tcp.h Makefile
  2562. Xrefuse.o: log_tcp.h Makefile
  2563. Xrfc931.o: log_tcp.h Makefile
  2564. Xshell_cmd.o: log_tcp.h Makefile
  2565. Xtcpd.o: patchlevel.h log_tcp.h Makefile
  2566. Xtry.o: log_tcp.h Makefile
  2567. END_OF_Makefile.dist
  2568. if test 15575 -ne `wc -c <Makefile.dist`; then
  2569.     echo shar: \"Makefile.dist\" unpacked with wrong size!
  2570. fi
  2571. # end of overwriting check
  2572. fi
  2573. if test -f hosts_access.5 -a "${1}" != "-c" ; then 
  2574.   echo shar: Will not over-write existing file \"hosts_access.5\"
  2575. else
  2576. echo shar: Extracting \"hosts_access.5\" \(9533 characters\)
  2577. sed "s/^X//" >hosts_access.5 <<'END_OF_hosts_access.5'
  2578. X.TH HOSTS_ACCESS 5
  2579. X.SH NAME
  2580. Xhosts_access \- format of host access control files
  2581. X.SH DESCRIPTION
  2582. XThis manual page describes a simple access control language that is
  2583. Xbased on client (host name or address) and server (process name)
  2584. Xpatterns.  Examples are given at the end. The impatient reader can skip
  2585. Xto the EXAMPLES section for a quick introduction.
  2586. X.PP
  2587. XIn the following text, \fIdaemon\fR is the the process name of a
  2588. Xnetwork daemon process, and \fIclient\fR is the name and/or address of
  2589. Xa host requesting service. Network daemon process names are specified
  2590. Xin the inetd configuration file.
  2591. X.SH ACCESS CONTROL FILES
  2592. XThe access control software consults two files:
  2593. X.IP o
  2594. XAccess will be granted when a (daemon,client) pair matches an entry in
  2595. Xthe \fI/etc/hosts.allow\fR file.
  2596. X.IP o
  2597. XOtherwise, access will be denied when a (daemon,client) pair matches an
  2598. Xentry in the \fI/etc/hosts.deny\fR file.
  2599. X.IP o
  2600. XOtherwise, access will be granted.
  2601. X.PP
  2602. XA non-existing access control file is treated as if it were an empty
  2603. Xfile. Thus, access control can be turned off by providing no access
  2604. Xcontrol files.
  2605. X.SH ACCESS CONTROL RULES
  2606. XEach access control file consists of zero or more lines of text.  These
  2607. Xlines are processed in order of appearance. The search terminates when a
  2608. Xmatch is found.
  2609. X.IP o
  2610. XA newline character is ignored when it is preceded by a backslash
  2611. Xcharacter.
  2612. X.IP o
  2613. XBlank lines or lines that begin with a `#\' character are ignored.
  2614. X.IP o
  2615. XAll other lines should satisfy the following format, things between []
  2616. Xbeing optional:
  2617. X.sp
  2618. X.ti +3
  2619. Xdaemon_list : client_list [ : shell_command ]
  2620. X.PP
  2621. X\fIdaemon_list\fR is a list of one or more daemon process names
  2622. X(argv[0] values) or wildcards (see below).  
  2623. X.PP
  2624. X\fIclient_list\fR is a list
  2625. Xof one or more host names, host addresses, patterns or wildcards (see
  2626. Xbelow) that will be matched against the remote host name or address.
  2627. X.PP
  2628. XList elements should be separated by blanks and/or commas.  
  2629. X.PP
  2630. XWith the exception of NIS (YP) netgroup lookups, all access control
  2631. Xchecks are case insensitive.
  2632. X.br
  2633. X.ne 4
  2634. X.SH PATTERNS
  2635. XThe access control language implements the following patterns:
  2636. X.IP o
  2637. XA string that begins with a `.\' character.  A client name or address
  2638. Xis matched if its last components match the specified pattern.  For
  2639. Xexample, the pattern `.tue.nl\' matches the host name
  2640. X`wzv.win.tue.nl\'.
  2641. X.IP o
  2642. XA string that ends with a `.\' character.  A client name or address is
  2643. Xmatched if its first fields match the given string.  For example, the
  2644. Xpattern `131.155.\' matches the address of (almost) every host on the
  2645. XEind\%hoven University network (131.155.x.x).
  2646. X.IP o
  2647. XA string that begins with a `@\' character is treated as a netgroup
  2648. Xname.  Netgroups are usually supported on systems with NIS (formerly
  2649. XYP) data bases. A client host name is matched if it is a (host) member
  2650. Xof the specified netgroup.
  2651. X.IP o
  2652. XAn expression of the form `n.n.n.n/m.m.m.m\' is interpreted as a
  2653. X`net/mask\' pair. A client address is matched if `net\' is equal to the
  2654. Xbitwise AND of the address and the `mask\'. For example, the net/mask
  2655. Xpattern `131.155.72.0/255.255.254.0\' matches every address in the
  2656. Xrange `131.155.72.0\' through `131.155.73.255\'.
  2657. X.SH WILDCARDS
  2658. XThe access control language supports explicit wildcards:
  2659. X.IP ALL
  2660. XIf this token appears in a daemon_list, it matches all network daemon
  2661. Xprocess names.  If the ALL token appears in a client_list, it matches
  2662. Xall client names and addresses.
  2663. X.IP LOCAL
  2664. XMatches any string that does not contain a dot character.
  2665. XTypical use is in client_lists.
  2666. X.IP UNKNOWN
  2667. XMatches any host whose name and/or address lookup failed.  Should be
  2668. Xused with care, because host names may also be unavailable due to
  2669. Xtemporary name server problems.
  2670. X.IP FAIL
  2671. XLike the ALL wildcard, but causes the software to pretend that the scan
  2672. Xof the current access control table fails. FAIL is being phased out; it
  2673. Xwill become an undocumented feature. The EXCEPT operator (see below) is
  2674. Xa much cleaner alternative.
  2675. X.br
  2676. X.ne 6
  2677. X.SH OPERATORS
  2678. X.IP EXCEPT
  2679. XIntended use is of the form: `list_1 EXCEPT list_2\'; this construct
  2680. Xmatches anything that matches \fIlist_1\fR unless it matches
  2681. X\fIlist_2\fR.  This construct can be used in daemon_lists and in
  2682. Xclient_lists. The EXCEPT operator can be nested and is
  2683. Xright-associative (just like C's assignment operator).
  2684. X.br
  2685. X.ne 6
  2686. X.SH SHELL COMMANDS
  2687. XIf the first-matched access control rule contains a shell command, that
  2688. Xcommand is subjected to the following substitutions:
  2689. X.IP %a
  2690. Xexpands to the remote host address.
  2691. X.IP %c
  2692. Xexpands to client information: user@host, user@address, a host name, or
  2693. Xjust an address, depending on how much information is available.
  2694. X.IP %h
  2695. Xexpands to the remote host name (or address, if the host name is
  2696. Xunavailable).
  2697. X.IP %d
  2698. Xexpands to the daemon process name (argv[0] value).
  2699. X.IP %p
  2700. Xexpands to the daemon process id.
  2701. X.IP %u
  2702. Xexpands to the remote user name (or "unknown").
  2703. X.IP %%
  2704. Xexpands to a single `%\' character.
  2705. X.PP
  2706. XCharacters in % expansions that may confuse the shell are replaced by
  2707. Xunderscores.
  2708. XThe result is executed by a \fI/bin/sh\fR child process with standard
  2709. Xinput, output and error connected to \fI/dev/null\fR.  Specify an `&\'
  2710. Xat the end of the command if you do not want to wait until it has
  2711. Xcompleted.
  2712. X.PP
  2713. XShell commands should not rely on the PATH setting of the inetd.
  2714. XInstead, they should use absolute path names, or they should begin with
  2715. Xan explicit PATH=whatever statement.
  2716. X.SH EXAMPLES
  2717. XThe language is flexible enough that different types of access control
  2718. Xpolicy can be expressed with a minimum of fuss. Although the language
  2719. Xuses two access control tables, the most common policies can be
  2720. Ximplemented with one of the tables being trivial or even empty.
  2721. X.PP
  2722. XWhen reading the examples below it is important to realize that the
  2723. Xallow table is scanned before the deny table, that the search
  2724. Xterminates when a match is found, and that access is granted when no
  2725. Xmatch is found at all.
  2726. X.PP
  2727. XThe examples use host and domain names. They can be improved by
  2728. Xincluding address and/or network/netmask information, to reduce the
  2729. Ximpact of temporary name server lookup failures.
  2730. X.SH MOSTLY CLOSED
  2731. XIn this case, access is denied by default. Only explicitly authorized
  2732. Xhosts are permitted access. 
  2733. X.PP
  2734. XThe default policy (no access) is implemented with a trivial deny
  2735. Xfile:
  2736. X.PP
  2737. X.ne 2
  2738. X/etc/hosts.deny: 
  2739. X.in +3
  2740. XALL: ALL
  2741. X.PP
  2742. XThis denies all service to all hosts, unless they are permitted access
  2743. Xby entries in the allow file.
  2744. X.PP
  2745. XThe explicitly authorized hosts are listed in the allow file.
  2746. XFor example:
  2747. X.PP
  2748. X.ne 2
  2749. X/etc/hosts.allow: 
  2750. X.in +3
  2751. XALL: LOCAL @some_netgroup
  2752. X.br
  2753. XALL: .foobar.edu EXCEPT terminalserver.foobar.edu
  2754. X.PP
  2755. XThe first rule permits access to all services from hosts in the local
  2756. Xdomain (no `.\' in the host name) and from members of the
  2757. X\fIsome_netgroup\fP netgroup. The second rule permits access to all
  2758. Xservices from all hosts in the \fI.foobar.edu\fP domain, with the
  2759. Xexception of \fIterminalserver.foobar.edu\fP.
  2760. X.SH MOSTLY OPEN
  2761. XHere, access is granted by default; only explicitly specified hosts are
  2762. Xrefused service. 
  2763. X.PP
  2764. XThe default policy (access granted) makes the allow file redundant so
  2765. Xthat it can be omitted.  The explicitly non-authorized hosts are listed
  2766. Xin the deny file. For example:
  2767. X.PP
  2768. X/etc/hosts.deny:
  2769. X.in +3
  2770. XALL: some.host.name, .some.domain
  2771. X.br
  2772. XALL EXCEPT in.fingerd: other.host.name, .other.domain
  2773. X.PP
  2774. XThe first rule denies some hosts all services; the second rule still
  2775. Xpermits finger requests from other hosts.
  2776. X.SH BOOBY TRAPS
  2777. XThe next example permits tftp requests from hosts in the local domain.
  2778. XRequests from any other hosts are denied. Instead of the requested
  2779. Xfile, a finger probe is sent to the offending host. The result is
  2780. Xmailed to the superuser.
  2781. X.PP
  2782. X.ne 2
  2783. X/etc/hosts.allow:
  2784. X.in +3
  2785. X.nf
  2786. Xin.tftpd: LOCAL, .my.domain
  2787. X.PP
  2788. X.ne 2
  2789. X/etc/hosts.deny:
  2790. X.in +3
  2791. X.nf
  2792. Xin.tftpd: ALL: (/usr/ucb/finger -l @%h | /usr/ucb/mail -s %d-%h root) &
  2793. X.fi
  2794. X.PP
  2795. XThe expansion of the %h (remote host) and %d (service name) sequences
  2796. Xis described in the section on shell commands.
  2797. X.PP
  2798. XWarning: do not booby-trap your finger daemon, unless you are prepared
  2799. Xfor infinite finger loops.
  2800. X.PP
  2801. XOn network firewall systems this trick can be carried even further.
  2802. XThe typical network firewall only provides a limited set of services to
  2803. Xthe outer world. All other services can be "bugged" just like the above
  2804. Xtftp example. The result is an excellent early-warning system.
  2805. X.br
  2806. X.ne 4
  2807. X.SH DIAGNOSTICS
  2808. XAn error is reported when a syntax error is found in a host access
  2809. Xcontrol rule; when the length of an access control rule exceeds the
  2810. Xcapacity of an internal buffer; when an access control rule is not
  2811. Xterminated by a newline character; when the result of %<character>
  2812. Xexpansion would overflow an internal buffer; when a system call fails
  2813. Xthat shouldn\'t.  All problems are reported via the syslog daemon.
  2814. X.SH FILES
  2815. X.na
  2816. X.nf
  2817. X/etc/hosts.allow, (daemon,client) pairs that are granted access.
  2818. X/etc/hosts.deny, (daemon,client) pairs that are denied access.
  2819. X.ad
  2820. X.fi
  2821. X.SH SEE ALSO
  2822. Xtcpd(8) tcp/ip daemon wrapper program.
  2823. X.SH BUGS
  2824. XIf a name server lookup times out, the host name will not be available
  2825. Xto the access control software, even though the host is registered.
  2826. X.PP
  2827. XDomain name server lookups are case insensitive; NIS (formerly YP)
  2828. Xnetgroup lookups are case sensitive.
  2829. X.SH AUTHOR
  2830. X.na
  2831. X.nf
  2832. XWietse Venema (wietse@wzv.win.tue.nl)
  2833. XDepartment of Mathematics and Computing Science
  2834. XEindhoven University of Technology
  2835. XDen Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  2836. X\" @(#) hosts_access.5 1.11 93/03/07 22:47:47
  2837. END_OF_hosts_access.5
  2838. if test 9533 -ne `wc -c <hosts_access.5`; then
  2839.     echo shar: \"hosts_access.5\" unpacked with wrong size!
  2840. fi
  2841. # end of overwriting check
  2842. fi
  2843. if test -f strcasecmp.c -a "${1}" != "-c" ; then 
  2844.   echo shar: Will not over-write existing file \"strcasecmp.c\"
  2845. else
  2846. echo shar: Extracting \"strcasecmp.c\" \(3767 characters\)
  2847. sed "s/^X//" >strcasecmp.c <<'END_OF_strcasecmp.c'
  2848. X/*
  2849. X * Copyright (c) 1987 Regents of the University of California.
  2850. X * All rights reserved.
  2851. X *
  2852. X * Redistribution and use in source and binary forms are permitted
  2853. X * provided that the above copyright notice and this paragraph are
  2854. X * duplicated in all such forms and that any documentation,
  2855. X * advertising materials, and other materials related to such
  2856. X * distribution and use acknowledge that the software was developed
  2857. X * by the University of California, Berkeley.  The name of the
  2858. X * University may not be used to endorse or promote products derived
  2859. X * from this software without specific prior written permission.
  2860. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  2861. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  2862. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  2863. X */
  2864. X
  2865. X#if defined(LIBC_SCCS) && !defined(lint)
  2866. Xstatic char sccsid[] = "@(#)strcasecmp.c    5.6 (Berkeley) 6/27/88";
  2867. X#endif /* LIBC_SCCS and not lint */
  2868. X
  2869. X#include <sys/types.h>
  2870. X
  2871. X/*
  2872. X * This array is designed for mapping upper and lower case letter
  2873. X * together for a case independent comparison.  The mappings are
  2874. X * based upon ascii character sequences.
  2875. X */
  2876. Xstatic u_char charmap[] = {
  2877. X    '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
  2878. X    '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
  2879. X    '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
  2880. X    '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
  2881. X    '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
  2882. X    '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
  2883. X    '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
  2884. X    '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
  2885. X    '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  2886. X    '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  2887. X    '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  2888. X    '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
  2889. X    '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  2890. X    '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  2891. X    '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  2892. X    '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
  2893. X    '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
  2894. X    '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
  2895. X    '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
  2896. X    '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
  2897. X    '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
  2898. X    '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
  2899. X    '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
  2900. X    '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
  2901. X    '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  2902. X    '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  2903. X    '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  2904. X    '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
  2905. X    '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  2906. X    '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  2907. X    '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  2908. X    '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
  2909. X};
  2910. X
  2911. Xstrcasecmp(s1, s2)
  2912. X    char *s1, *s2;
  2913. X{
  2914. X    register u_char    *cm = charmap,
  2915. X            *us1 = (u_char *)s1,
  2916. X            *us2 = (u_char *)s2;
  2917. X
  2918. X    while (cm[*us1] == cm[*us2++])
  2919. X        if (*us1++ == '\0')
  2920. X            return(0);
  2921. X    return(cm[*us1] - cm[*--us2]);
  2922. X}
  2923. X
  2924. Xstrncasecmp(s1, s2, n)
  2925. X    char *s1, *s2;
  2926. X    register int n;
  2927. X{
  2928. X    register u_char    *cm = charmap,
  2929. X            *us1 = (u_char *)s1,
  2930. X            *us2 = (u_char *)s2;
  2931. X
  2932. X    while (--n >= 0 && cm[*us1] == cm[*us2++])
  2933. X        if (*us1++ == '\0')
  2934. X            return(0);
  2935. X    return(n < 0 ? 0 : cm[*us1] - cm[*--us2]);
  2936. X}
  2937. END_OF_strcasecmp.c
  2938. if test 3767 -ne `wc -c <strcasecmp.c`; then
  2939.     echo shar: \"strcasecmp.c\" unpacked with wrong size!
  2940. fi
  2941. # end of overwriting check
  2942. fi
  2943. if test -f BLURB -a "${1}" != "-c" ; then 
  2944.   echo shar: Will not over-write existing file \"BLURB\"
  2945. else
  2946. echo shar: Extracting \"BLURB\" \(2068 characters\)
  2947. sed "s/^X//" >BLURB <<'END_OF_BLURB'
  2948. X@(#) BLURB 1.8 93/03/24 22:42:37
  2949. X
  2950. XWith the programs that come with this kit you can monitor incoming
  2951. Xrequests for IP services such as TFTP, EXEC, FTP, RSH, TELNET, RLOGIN,
  2952. XFINGER, SYSTAT, and many others.
  2953. X
  2954. XOptional features are: access control based on pattern matching; remote
  2955. Xusername lookup using the RFC 931 protocol; protection against attacks
  2956. Xfrom hosts that pretend to have someone elses name; protection against
  2957. Xattacks from hosts that pretend to have someone elses network address.
  2958. X
  2959. XThe programs can be installed without requiring any changes to existing
  2960. Xsoftware or configuration files. By default, they just log the remote
  2961. Xhost name and do some sanity checks on the origin the request. No
  2962. Xinformation is exchanged with the remote client process.
  2963. X
  2964. XThe most notable differences with respect to the previous release are:
  2965. X
  2966. X    - Optional protection against attacks from hosts that pretend to
  2967. X    have someone elses network address. For example, the address of a
  2968. X    trusted host within your own network.
  2969. X
  2970. X    - The access control language has been extended with a simple but
  2971. X    powerful operator that greatly simplifies the design of rule sets
  2972. X    (ALL: .foo.edu EXCEPT dialup.foo.edu). Blank lines are permitted,
  2973. X    and long lines can be continued with backslash-newline.
  2974. X
  2975. X    - All configurable stuff, including path names, has been moved into
  2976. X    the Makefile so that you no longer have to hack source code to just
  2977. X    configure the programs.
  2978. X
  2979. X    - Ported to Solaris 2. TLI-based applications not yet supported.
  2980. X    Several workarounds for System V bugs.
  2981. X
  2982. X    - A small loophole in the netgroup lookup code was closed, and the
  2983. X    remote username lookup code was made more portable.
  2984. X
  2985. X    - Still more documentation. The README file now provides tutorial
  2986. X    sections with introductions to client, server, inetd and syslogd.
  2987. X
  2988. XThe default mode of operation should be backwards compatible with
  2989. Xearlier versions.
  2990. X
  2991. X    Wietse Venema (wietse@wzv.win.tue.nl),
  2992. X    Department of Mathematics and Computing Science,
  2993. X    Eindhoven University of Technology,
  2994. X    The Netherlands.
  2995. END_OF_BLURB
  2996. if test 2068 -ne `wc -c <BLURB`; then
  2997.     echo shar: \"BLURB\" unpacked with wrong size!
  2998. fi
  2999. # end of overwriting check
  3000. fi
  3001. if test -f rfc931.c -a "${1}" != "-c" ; then 
  3002.   echo shar: Will not over-write existing file \"rfc931.c\"
  3003. else
  3004. echo shar: Extracting \"rfc931.c\" \(3825 characters\)
  3005. sed "s/^X//" >rfc931.c <<'END_OF_rfc931.c'
  3006. X /*
  3007. X  * rfc931_user() speaks a common subset of the RFC 931, AUTH, TAP and IDENT
  3008. X  * protocols. It consults an RFC 931 etc. compatible daemon on the client
  3009. X  * host to look up the remote user name. The information should not be used
  3010. X  * for authentication purposes.
  3011. X  * 
  3012. X  * Diagnostics are reported through syslog(3).
  3013. X  * 
  3014. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  3015. X  * 
  3016. X  * Inspired by the authutil package (comp.sources.unix volume 22) by Dan
  3017. X  * Bernstein (brnstnd@kramden.acf.nyu.edu).
  3018. X  */
  3019. X
  3020. X#ifndef lint
  3021. Xstatic char sccsid[] = "@(#) rfc931.c 1.4 93/03/07 22:47:52";
  3022. X#endif
  3023. X
  3024. X#include <stdio.h>
  3025. X#include <syslog.h>
  3026. X#include <sys/types.h>
  3027. X#include <sys/socket.h>
  3028. X#include <netinet/in.h>
  3029. X#include <setjmp.h>
  3030. X#include <signal.h>
  3031. X
  3032. X#include "log_tcp.h"
  3033. X
  3034. X#define    RFC931_PORT    113        /* Semi-well-known port */
  3035. X
  3036. X#ifndef RFC931_TIMEOUT
  3037. X#define    RFC931_TIMEOUT    30        /* wait for at most 30 seconds */
  3038. X#endif
  3039. X
  3040. Xextern char *strchr();
  3041. Xextern char *inet_ntoa();
  3042. X
  3043. Xstatic jmp_buf timebuf;
  3044. X
  3045. X/* timeout - handle timeouts */
  3046. X
  3047. Xstatic void timeout(sig)
  3048. Xint     sig;
  3049. X{
  3050. X    longjmp(timebuf, sig);
  3051. X}
  3052. X
  3053. X/* rfc931_name - return remote user name */
  3054. X
  3055. Xchar   *rfc931_name(there)
  3056. Xstruct sockaddr_in *there;        /* remote link information */
  3057. X{
  3058. X    struct sockaddr_in here;        /* local link information */
  3059. X    struct sockaddr_in sin;        /* for talking to RFC931 daemon */
  3060. X    int     length;
  3061. X    int     s;
  3062. X    unsigned remote;
  3063. X    unsigned local;
  3064. X    static char user[256];        /* XXX */
  3065. X    char    buffer[512];        /* YYY */
  3066. X    FILE   *fp;
  3067. X    char   *cp;
  3068. X    char   *result = FROM_UNKNOWN;
  3069. X
  3070. X    /* Find out local address and port number of stdin. */
  3071. X
  3072. X    length = sizeof(here);
  3073. X    if (getsockname(0, (struct sockaddr *) & here, &length) == -1) {
  3074. X    syslog(LOG_ERR, "getsockname: %m");
  3075. X    return (result);
  3076. X    }
  3077. X
  3078. X    /*
  3079. X     * The socket that will be used for user name lookups should be bound to
  3080. X     * the same local IP address as stdin. This will automagically happen on
  3081. X     * hosts that have only one IP network address. When the local host has
  3082. X     * more than one IP network address, we must do an explicit bind() call.
  3083. X     */
  3084. X
  3085. X    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  3086. X    return (result);
  3087. X
  3088. X    sin = here;
  3089. X    sin.sin_port = 0;
  3090. X    if (bind(s, (struct sockaddr *) & sin, sizeof sin) < 0) {
  3091. X    syslog(LOG_ERR, "bind: %s: %m", inet_ntoa(here.sin_addr));
  3092. X    return (result);
  3093. X    }
  3094. X    /* Set up timer so we won't get stuck. */
  3095. X
  3096. X    signal(SIGALRM, timeout);
  3097. X    if (setjmp(timebuf)) {
  3098. X    close(s);                /* not: fclose(fp) */
  3099. X    return (result);
  3100. X    }
  3101. X    alarm(RFC931_TIMEOUT);
  3102. X
  3103. X    /* Connect to the RFC931 daemon. */
  3104. X
  3105. X    sin = *there;
  3106. X    sin.sin_port = htons(RFC931_PORT);
  3107. X    if (connect(s, (struct sockaddr *) & sin, sizeof(sin)) == -1
  3108. X    || (fp = fdopen(s, "w+")) == 0) {
  3109. X    close(s);
  3110. X    alarm(0);
  3111. X    return (result);
  3112. X    }
  3113. X
  3114. X    /*
  3115. X     * Use unbuffered I/O or we may read back our own query. setbuf() must be
  3116. X     * called before doing any I/O on the stream. Thanks for the reminder,
  3117. X     * Paul Kranenburg <pk@cs.few.eur.nl>!
  3118. X     */
  3119. X
  3120. X    setbuf(fp, (char *) 0);
  3121. X
  3122. X    /* Query the RFC 931 server. Would 13-byte writes ever be broken up? */
  3123. X
  3124. X    fprintf(fp, "%u,%u\r\n", ntohs(there->sin_port), ntohs(here.sin_port));
  3125. X    fflush(fp);
  3126. X
  3127. X    /*
  3128. X     * Read response from server. Use fgets()/sscanf() instead of fscanf()
  3129. X     * because there is no buffer for pushback. Thanks, Chris Turbeville
  3130. X     * <turbo@cse.uta.edu>.
  3131. X     */
  3132. X
  3133. X    if (fgets(buffer, sizeof(buffer), fp) != 0
  3134. X    && ferror(fp) == 0 && feof(fp) == 0
  3135. X    && sscanf(buffer, "%u , %u : USERID :%*[^:]:%255s",
  3136. X          &remote, &local, user) == 3
  3137. X    && ntohs(there->sin_port) == remote
  3138. X    && ntohs(here.sin_port) == local) {
  3139. X    /* Strip trailing carriage return. */
  3140. X
  3141. X    if (cp = strchr(user, '\r'))
  3142. X        *cp = 0;
  3143. X    result = user;
  3144. X    }
  3145. X    alarm(0);
  3146. X    fclose(fp);
  3147. X    return (result);
  3148. X}
  3149. END_OF_rfc931.c
  3150. if test 3825 -ne `wc -c <rfc931.c`; then
  3151.     echo shar: \"rfc931.c\" unpacked with wrong size!
  3152. fi
  3153. # end of overwriting check
  3154. fi
  3155. if test -f tcpd.8 -a "${1}" != "-c" ; then 
  3156.   echo shar: Will not over-write existing file \"tcpd.8\"
  3157. else
  3158. echo shar: Extracting \"tcpd.8\" \(6757 characters\)
  3159. sed "s/^X//" >tcpd.8 <<'END_OF_tcpd.8'
  3160. X.TH TCPD 8
  3161. X.SH NAME
  3162. Xtcpd \- access control facility for internet services
  3163. X.SH DESCRIPTION
  3164. X.PP
  3165. XThe \fItcpd\fR program can be set up to monitor incoming requests for
  3166. X\fItelnet\fR, \fIfinger\fR, \fIftp\fR, \fIexec\fR, \fIrsh\fR,
  3167. X\fIrlogin\fR, \fItftp\fR, \fItalk\fR, \fIcomsat\fR and other services
  3168. Xthat have a one-to-one mapping onto executable files.
  3169. X.PP
  3170. XOperation is as follows: whenever a request for internet service
  3171. Xarrives, the \fIinetd\fP daemon is tricked into running the \fItcpd\fP
  3172. Xprogram instead of the desired server. \fItcpd\fP logs the request and
  3173. Xdoes some additional checks. When all is well, \fItcpd\fP runs the
  3174. Xappropriate server program and goes away.
  3175. X.PP
  3176. XOptional features are: pattern-based access control, patterns, remote
  3177. Xusername lookups with the RFC 931 protocol, protection against hosts
  3178. Xthat pretend to have someone elses host name, and protection against
  3179. Xhosts that pretend to have someone elses network address.
  3180. X.SH LOGGING
  3181. XConnections that are monitored by
  3182. X.I tcpd
  3183. Xare reported through the \fIsyslog\fR(3) facility. Each record contains
  3184. Xa time stamp, the remote host name and the name of the service
  3185. Xrequested. The information can be useful to detect unwanted activities,
  3186. Xespecially when logfile information from several hosts is merged.
  3187. X.PP
  3188. XIn order to find out where your logs are going, examine the syslog
  3189. Xconfiguration file, usually /etc/syslog.conf.
  3190. X.SH ACCESS CONTROL
  3191. XOptionally,
  3192. X.I tcpd
  3193. Xsupports a simple form of access control that is based on pattern
  3194. Xmatching.  The access-control software provides hooks for the execution
  3195. Xof shell commands when a pattern fires.  For details, see the
  3196. X\fIhosts_access\fR(5) manual page.
  3197. X.SH HOST NAME VERIFICATION
  3198. XThe authentication scheme of some protocols (\fIrlogin, rsh\fR) relies
  3199. Xon host names. Some implementations believe the host name that they get
  3200. Xfrom any random name server; other implementations are more careful but
  3201. Xuse a flawed algorithm.
  3202. X.PP
  3203. X.I tcpd
  3204. Xverifies the remote host name that is returned by the address->name DNS
  3205. Xserver by looking at the host name and address that are returned by the
  3206. Xname->address DNS server.  If any discrepancy is detected,
  3207. X.I tcpd
  3208. Xconcludes that it is dealing with a host that pretends to have someone
  3209. Xelses host name.
  3210. X.PP
  3211. XIf the sources are compiled with the \*QPARANOID\*U option,
  3212. X.I tcpd
  3213. Xwill drop the connection in case of a host name/address mismatch.
  3214. XOtherwise,
  3215. X.I tcpd
  3216. Xjust pretends that host name lookup failed when logging the connection
  3217. Xand consulting the optional access control tables.
  3218. X.SH HOST ADDRESS SPOOFING
  3219. XBy default,
  3220. X.I tcpd
  3221. Xdisables source-routing socket options on every connection that it
  3222. Xdeals with. This will take care of most attacks from hosts that pretend
  3223. Xto have an address that belongs to someone elses network. UDP services
  3224. Xdo not benefit from this protection.
  3225. X.SH RFC 931
  3226. XWhen RFC 931 lookups are enabled (compile-time option) \fItcpd\fR will
  3227. Xattempt to establish the name of the remote user. This will succeed
  3228. Xonly if the client host runs an RFC 931-compliant daemon.  Remote user
  3229. Xname lookups will not work for datagram-oriented connections, and may
  3230. Xcause noticeable delays in the case of connections from PCs.
  3231. X.SH EXAMPLES
  3232. XThe details of using \fItcpd\fR depend on pathname information that was
  3233. Xcompiled into the program.
  3234. X.SH EXAMPLE 1
  3235. XThis example applies when \fItcpd\fR expects that the original network
  3236. Xdaemons will be moved to a "secret" place.
  3237. X.PP
  3238. XIn order to monitor access to the \fIfinger\fR service, move the
  3239. Xoriginal finger daemon to the "secret" place and install tcpd in the
  3240. Xplace of the original finger daemon. No changes are required to
  3241. Xconfiguration files.
  3242. X.nf
  3243. X.sp
  3244. X.in +5
  3245. X# mkdir /secret/place
  3246. X# mv /usr/etc/in.fingerd /secret/place
  3247. X# cp tcpd /usr/etc/in.fingerd
  3248. X.fi
  3249. X.PP
  3250. XThe example assumes that the network daemons live in /usr/etc. On some
  3251. Xsystems, network daemons live in /usr/sbin or in /usr/libexec, or have
  3252. Xno `in.\' prefix to their name.
  3253. X.SH EXAMPLE 2
  3254. XThis example applies when \fItcpd\fR expects that the network daemons
  3255. Xare left in their original place.
  3256. X.PP
  3257. XIn order to monitor access to the \fIfinger\fR service, perform the
  3258. Xfollowing edits on the \fIinetd\fR configuration file (usually 
  3259. X\fI/etc/inetd.conf\fR or \fI/etc/inet/inetd.conf\fR):
  3260. X.nf
  3261. X.sp
  3262. X.ti +5
  3263. Xfinger  stream  tcp  nowait  nobody  /usr/etc/in.fingerd  in.fingerd
  3264. X.sp
  3265. Xbecomes:
  3266. X.sp
  3267. X.ti +5
  3268. Xfinger  stream  tcp  nowait  nobody  /some/where/tcpd     in.fingerd
  3269. X.sp
  3270. X.fi
  3271. X.PP
  3272. XThe example assumes that the network daemons live in /usr/etc. On some
  3273. Xsystems, network daemons live in /usr/sbin or in /usr/libexec, the
  3274. Xdaemons have no `in.\' prefix to their name, or there is no userid
  3275. Xfield in the inetd configuration file.
  3276. X.PP
  3277. XSimilar changes will be needed for the other services that are to be
  3278. Xcovered by \fItcpd\fR.  Send a `kill -HUP\' to the \fIinetd\fR(8)
  3279. Xprocess to make the changes effective.
  3280. X.SH EXAMPLE 3
  3281. XIn the case of daemons that do not live in a common directory ("secret"
  3282. Xor otherwise), edit the \fIinetd\fR configuration file so that it
  3283. Xspecifies an absolute path name for the process name field. For example:
  3284. X.nf
  3285. X.sp
  3286. X    ntalk  dgram  udp  wait  root  /some/where/tcpd  /usr/local/lib/ntalkd
  3287. X.sp
  3288. X.fi
  3289. X.PP
  3290. XOnly the last component (ntalkd) of the process name will be used for
  3291. Xaccess control and logging.
  3292. X.SH BUGS
  3293. XSome UDP (and RPC) daemons linger around for a while after they have
  3294. Xfinished their work, in case another request comes in.  In the inetd
  3295. Xconfiguration file these services are registered with the \fIwait\fR
  3296. Xoption. Only the request that started such a daemon will be logged.
  3297. X.PP
  3298. XThe program does not work with RPC services over TCP. These services
  3299. Xare registered as \fIrpc/tcp\fR in the inetd configuration file. The
  3300. Xonly non-trivial service that is affected by this limitation is
  3301. X\fIrexd\fR, which is used by the \fIon(1)\fR command. This is no great
  3302. Xloss.  On most systems, \fIrexd\fR is less secure than a wildcard in
  3303. X/etc/hosts.equiv.
  3304. X.PP
  3305. XRPC broadcast requests (for example: \fIrwall, rup, rusers\fR) always
  3306. Xappear to come from the responding host. What happens is that the
  3307. Xclient broadcasts the request to all \fIportmap\fR daemons on its
  3308. Xnetwork; each \fIportmap\fR daemon forwards the request to a local
  3309. Xdaemon. As far as the \fIrwall\fR etc.  daemons know, the request comes
  3310. Xfrom the local host.
  3311. X.SH FILES
  3312. X.PP
  3313. XThe default locations of the host access control tables are:
  3314. X.PP
  3315. X/etc/hosts.allow
  3316. X.br
  3317. X/etc/hosts.deny
  3318. X.SH SEE ALSO
  3319. X.na
  3320. X.nf
  3321. Xhosts_access(5), format of the tcpd access control tables.
  3322. Xsyslog.conf(5), format of the syslogd control file.
  3323. Xinetd.conf(5), format of the inetd control file.
  3324. X.SH AUTHORS
  3325. X.na
  3326. X.nf
  3327. XWietse Venema (wietse@wzv.win.tue.nl),
  3328. XDepartment of Mathematics and Computing Science,
  3329. XEindhoven University of Technology,
  3330. XThe Netherlands.
  3331. X\" @(#) tcpd.8 1.2 93/03/07 22:47:54
  3332. END_OF_tcpd.8
  3333. if test 6757 -ne `wc -c <tcpd.8`; then
  3334.     echo shar: \"tcpd.8\" unpacked with wrong size!
  3335. fi
  3336. # end of overwriting check
  3337. fi
  3338. if test -f hosts_info.c -a "${1}" != "-c" ; then 
  3339.   echo shar: Will not over-write existing file \"hosts_info.c\"
  3340. else
  3341. echo shar: Extracting \"hosts_info.c\" \(788 characters\)
  3342. sed "s/^X//" >hosts_info.c <<'END_OF_hosts_info.c'
  3343. X /*
  3344. X  * hosts_info() returns a string with as much information about the origin
  3345. X  * of a connection as we have: the user name, if known, and the host name,
  3346. X  * or the host address if the name is not available.
  3347. X  * 
  3348. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  3349. X  */
  3350. X
  3351. X#ifndef lint
  3352. Xstatic char sccsid[] = "@(#) hosts_info.c 1.1 92/06/11 22:21:44";
  3353. X#endif
  3354. X
  3355. X#include <stdio.h>
  3356. X
  3357. X#include "log_tcp.h"
  3358. X
  3359. X/* hosts_info - return string with as much about the client as we know */
  3360. X
  3361. Xchar   *hosts_info(client)
  3362. Xstruct from_host *client;
  3363. X{
  3364. X    static char buf[BUFSIZ];        /* XXX */
  3365. X
  3366. X    if (client->user[0] && strcmp(client->user, FROM_UNKNOWN)) {
  3367. X    sprintf(buf, "%s@%s", client->user, FROM_HOST(client));
  3368. X    return (buf);
  3369. X    } else {
  3370. X    return (FROM_HOST(client));
  3371. X    }
  3372. X}
  3373. END_OF_hosts_info.c
  3374. if test 788 -ne `wc -c <hosts_info.c`; then
  3375.     echo shar: \"hosts_info.c\" unpacked with wrong size!
  3376. fi
  3377. # end of overwriting check
  3378. fi
  3379. if test -f hosts_access.3 -a "${1}" != "-c" ; then 
  3380.   echo shar: Will not over-write existing file \"hosts_access.3\"
  3381. else
  3382. echo shar: Extracting \"hosts_access.3\" \(2018 characters\)
  3383. sed "s/^X//" >hosts_access.3 <<'END_OF_hosts_access.3'
  3384. X.TH HOSTS_ACCESS 3
  3385. X.SH
  3386. Xhosts_access, hosts_ctl \- access control library
  3387. X.SH SYNOPSIS
  3388. X.nf
  3389. X#include "log_tcp.h"
  3390. X
  3391. Xint hosts_access(daemon, client)
  3392. Xchar *daemon;
  3393. Xstruct from_host *client;
  3394. X
  3395. Xint hosts_ctl(daemon, client_name, client_addr, client_user)
  3396. Xchar *daemon;
  3397. Xchar *client_host;
  3398. Xchar *client_addr;
  3399. Xchar *client_user;
  3400. X.fi
  3401. X.SH DESCRIPTION
  3402. XThe routines described in this document are part of the \fIlibwrap.a\fR
  3403. Xlibrary. They implement a pattern-based access control language with
  3404. Xoptional shell commands that are executed when a pattern fires.
  3405. X.PP
  3406. XIn all cases, the daemon argument should specify a daemon process name
  3407. X(argv[0] value).  The client host address should be a valid address, or
  3408. XFROM_UNKNOWN if address lookup failed. The client host name and user
  3409. Xname should be empty strings if no information is available,
  3410. XFROM_UNKNOWN if lookup failed, or an actual host or user name.
  3411. X.PP
  3412. Xhosts_access() consults the access control tables described in the
  3413. X\fIhosts_access(5)\fR manual page.  If a match is found, an optional
  3414. Xshell command is executed and the search terminates. hosts_access()
  3415. Xreturns zero if access should be denied.
  3416. X.PP
  3417. Xhosts_ctl() is a wrapper around the hosts_access() routine with a
  3418. Xperhaps more convenient interface.  hosts_ctl() returns zero if access
  3419. Xshould be denied.
  3420. X.SH DIAGNOSTICS
  3421. XProblems are reported via the syslog daemon.
  3422. X.SH SEE ALSO
  3423. Xhosts_access(5), format of the access control tables.
  3424. X.SH FILES
  3425. X/etc/hosts.access, /etc/hosts.deny, access control tables.
  3426. X.SH BUGS
  3427. XThe functions described here do not make copies of their string-valued
  3428. Xarguments.  Beware of data from functions that overwrite their results
  3429. Xupon each call.
  3430. X.sp
  3431. Xhosts_access() uses the strtok() library function. This may interfere
  3432. Xwith other code that relies on strtok().
  3433. X.SH AUTHOR
  3434. X.na
  3435. X.nf
  3436. XWietse Venema (wietse@wzv.win.tue.nl)
  3437. XDepartment of Mathematics and Computing Science
  3438. XEindhoven University of Technology
  3439. XDen Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  3440. X\" @(#) hosts_access.3 1.1 92/06/11 22:21:45
  3441. END_OF_hosts_access.3
  3442. if test 2018 -ne `wc -c <hosts_access.3`; then
  3443.     echo shar: \"hosts_access.3\" unpacked with wrong size!
  3444. fi
  3445. # end of overwriting check
  3446. fi
  3447. if test -f hosts_ctl.c -a "${1}" != "-c" ; then 
  3448.   echo shar: Will not over-write existing file \"hosts_ctl.c\"
  3449. else
  3450. echo shar: Extracting \"hosts_ctl.c\" \(969 characters\)
  3451. sed "s/^X//" >hosts_ctl.c <<'END_OF_hosts_ctl.c'
  3452. X /*
  3453. X  * hosts_ctl() combines the most common applications of the host access
  3454. X  * control library. routine. It bundles its arguments into a from_host
  3455. X  * structure, then calls the hosts_access() access control checker. The host
  3456. X  * name and user name arguments should be empty strings, "unknown" or real
  3457. X  * data. if a match is found, the optional shell command is executed.
  3458. X  * 
  3459. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  3460. X  */
  3461. X
  3462. X#ifndef lint
  3463. Xstatic char sccsid[] = "@(#) hosts_ctl.c 1.1 92/06/11 22:21:48";
  3464. X#endif
  3465. X
  3466. X#include <stdio.h>
  3467. X
  3468. X#include "log_tcp.h"
  3469. X
  3470. X/* hosts_ctl - general interface for the hosts_access() routine */
  3471. X
  3472. Xint     hosts_ctl(daemon, name, addr, user)
  3473. Xchar   *daemon;
  3474. Xchar   *name;
  3475. Xchar   *addr;
  3476. Xchar   *user;
  3477. X{
  3478. X    struct from_host client;
  3479. X    static struct from_host zeros;
  3480. X
  3481. X    client = zeros;
  3482. X    client.name = name;
  3483. X    client.addr = addr;
  3484. X    client.user = user;
  3485. X
  3486. X    return (hosts_access(daemon, &client));
  3487. X}
  3488. END_OF_hosts_ctl.c
  3489. if test 969 -ne `wc -c <hosts_ctl.c`; then
  3490.     echo shar: \"hosts_ctl.c\" unpacked with wrong size!
  3491. fi
  3492. # end of overwriting check
  3493. fi
  3494. if test -f percent_x.c -a "${1}" != "-c" ; then 
  3495.   echo shar: Will not over-write existing file \"percent_x.c\"
  3496. else
  3497. echo shar: Extracting \"percent_x.c\" \(2603 characters\)
  3498. sed "s/^X//" >percent_x.c <<'END_OF_percent_x.c'
  3499. X /*
  3500. X  * percent_x() takes a string and performs %a (host address), %c (client
  3501. X  * info), %h (host name or address), %d (daemon name), %p (process id) and
  3502. X  * %u (user name) substitutions. It aborts the program when the result of
  3503. X  * expansion would overflow the output buffer. Because the result of %<char>
  3504. X  * expansion is typically passed on to a shell process, characters that may
  3505. X  * confuse the shell are replaced by underscores.
  3506. X  * 
  3507. X  * Diagnostics are reported through syslog(3).
  3508. X  * 
  3509. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  3510. X  */
  3511. X
  3512. X#ifndef lint
  3513. Xstatic char sccsid[] = "@(#) percent_x.c 1.2 92/08/24 21:46:22";
  3514. X#endif
  3515. X
  3516. X/* System libraries. */
  3517. X
  3518. X#include <stdio.h>
  3519. X#include <syslog.h>
  3520. X
  3521. Xextern char *strncpy();
  3522. Xextern char *strchr();
  3523. Xextern void exit();
  3524. X
  3525. X/* Local stuff. */
  3526. X
  3527. X#include "log_tcp.h"
  3528. X
  3529. X/* percent_x - do %<char> expansion, abort if result buffer is too small */
  3530. X
  3531. Xvoid    percent_x(result, result_len, str, daemon, client, pid)
  3532. Xchar   *result;
  3533. Xint     result_len;
  3534. Xchar   *str;
  3535. Xchar   *daemon;
  3536. Xstruct from_host *client;
  3537. Xint     pid;
  3538. X{
  3539. X    char   *end = result + result_len - 1;    /* end of result buffer */
  3540. X    char   *expansion;
  3541. X    int     expansion_len;
  3542. X    char    pid_buf[10];
  3543. X    static char ok_chars[] = "1234567890!@%-_=+\\:,./\
  3544. Xabcdefghijklmnopqrstuvwxyz\
  3545. XABCDEFGHIJKLMNOPQRSTUVWXYZ";
  3546. X    char   *cp;
  3547. X
  3548. X    /*
  3549. X     * %a becomes the client address; %c all user and host information we
  3550. X     * have about the client; %d the daemon process name; %h the client host
  3551. X     * name or address; %p the daemon process id; %u the remote user name; %%
  3552. X     * becomes a %, and %other is ignored. We terminate with a diagnostic if
  3553. X     * we would overflow the result buffer. Characters that may confuse the
  3554. X     * shell are mapped to underscores.
  3555. X     */
  3556. X
  3557. X    while (*str) {
  3558. X    if (*str == '%') {
  3559. X        str++;
  3560. X        expansion =
  3561. X        *str == 'a' ? (str++, client->addr) :
  3562. X        *str == 'c' ? (str++, hosts_info(client)) :
  3563. X        *str == 'd' ? (str++, daemon) :
  3564. X        *str == 'h' ? (str++, FROM_HOST(client)) :
  3565. X        *str == 'p' ? (str++, sprintf(pid_buf, "%d", pid), pid_buf) :
  3566. X        *str == 'u' ? (str++, client->user) :
  3567. X        *str == '%' ? (str++, "%") :
  3568. X        *str == 0 ? "" : (str++, "");
  3569. X        expansion_len = strlen(expansion);
  3570. X        for (cp = expansion; *cp; cp++)
  3571. X        if (strchr(ok_chars, *cp) == 0)
  3572. X            *cp = '_';
  3573. X    } else {
  3574. X        expansion = str++;
  3575. X        expansion_len = 1;
  3576. X    }
  3577. X    if (result + expansion_len >= end) {
  3578. X        syslog(LOG_ERR, "shell command too long: %30s...", result);
  3579. X        exit(0);
  3580. X    }
  3581. X    strncpy(result, expansion, expansion_len);
  3582. X    result += expansion_len;
  3583. X    }
  3584. X    *result = 0;
  3585. X}
  3586. END_OF_percent_x.c
  3587. if test 2603 -ne `wc -c <percent_x.c`; then
  3588.     echo shar: \"percent_x.c\" unpacked with wrong size!
  3589. fi
  3590. # end of overwriting check
  3591. fi
  3592. if test -f options.c -a "${1}" != "-c" ; then 
  3593.   echo shar: Will not over-write existing file \"options.c\"
  3594. else
  3595. echo shar: Extracting \"options.c\" \(10084 characters\)
  3596. sed "s/^X//" >options.c <<'END_OF_options.c'
  3597. X /*
  3598. X  * General skeleton for adding options to the access control language. The
  3599. X  * Makefile describes how this alternative language is enabled. Shell
  3600. X  * commands will still be available, be it with a slightly different syntax.
  3601. X  * 
  3602. X  * The code uses a slightly different format of access control rules. It
  3603. X  * assumes that an access control rule looks like this:
  3604. X  * 
  3605. X  * daemon_list : client_list : option : option ...
  3606. X  * 
  3607. X  * An option is of the form "keyword" or "keyword = value". Option fields are
  3608. X  * processed from left to right. Blanks around keywords, "="  and values are
  3609. X  * optional. Blanks within values are left alone.
  3610. X  * 
  3611. X  * Diagnostics are reported through syslog(3).
  3612. X  * 
  3613. X  * Examples of options that are already implemented by the current skeleton:
  3614. X  * 
  3615. X  * user = nobody
  3616. X  * 
  3617. X  * Causes the process to switch its user id to that of "nobody". This normally
  3618. X  * requires root privilege.
  3619. X  * 
  3620. X  * group = tty
  3621. X  * 
  3622. X  * Causes the process to change its group id to that of the "tty" group. In
  3623. X  * order to switch both user and group ids you should normally switch the
  3624. X  * group id before switching the user id.
  3625. X  * 
  3626. X  * setenv = name value
  3627. X  * 
  3628. X  * places a name,value pair into the environment. The value is subjected to
  3629. X  * %<character> expansions.
  3630. X  * 
  3631. X  * spawn = (/usr/ucb/finger -l @%h | /usr/ucb/mail root) &
  3632. X  * 
  3633. X  * Executes (in a background child process) the shell command "finger -l @%h |
  3634. X  * mail root" after doing the %<character> expansions described in the
  3635. X  * hosts_access(5) manual page. The command is executed with stdin, stdout
  3636. X  * and stderr connected to the null device. Because options are processed in
  3637. X  * order, multiple spawn comands can be specified within the same access
  3638. X  * control rule, though "spawn = command1; command2" would be more
  3639. X  * efficient.
  3640. X  * 
  3641. X  * in.ftpd : ... : twist = /bin/echo 421 Some customized bounce message
  3642. X  * 
  3643. X  * Sends some custmized bounce message to the remote client instead of running
  3644. X  * the real ftp daemon. The command is subjected to %<character> expansion
  3645. X  * before execution by /bin/sh. Stdin, stdout and stderr are connected to the
  3646. X  * remote client process. The twist'ed command overlays the current process;
  3647. X  * it makes no sense to specify other options on the same line after a
  3648. X  * "twist". The "twist" option was inspired by Dan Bernstein's shuctl daemon
  3649. X  * wrapper control language.
  3650. X  * 
  3651. X  * umask = value
  3652. X  * 
  3653. X  * Sets the process file creation mask. Value must be an octal number.
  3654. X  * 
  3655. X  * If you compile with -DRFC_OPTION, code is enabled for the following option
  3656. X  * that does selective rfc931 lookups.
  3657. X  * 
  3658. X  * rfc931
  3659. X  * 
  3660. X  * Causes the daemon front ends to look up the remote user name with the RFC
  3661. X  * 931 protocol.
  3662. X  * 
  3663. X  * Warnings:
  3664. X  * 
  3665. X  * This module uses the non-reentrant strtok() library routine. The options
  3666. X  * argument to process_options() is destroyed.
  3667. X  * 
  3668. X  * There cannot be a ":" character in keywords or values. Backslash sequences
  3669. X  * are not yet recognized.
  3670. X  * 
  3671. X  * In case of UDP connections, do not "twist" commands that use the standard
  3672. X  * I/O or read(2)/write(2) routines to communicate with the client process;
  3673. X  * UDP requires other communications primitives.
  3674. X  * 
  3675. X  * In case of errors, use clean_exit() instead of directly calling exit(), or
  3676. X  * your inetd may loop on an UDP request.
  3677. X  */
  3678. X
  3679. X/* System libraries. */
  3680. X
  3681. X#include <sys/types.h>
  3682. X#include <sys/param.h>
  3683. X#include <sys/socket.h>
  3684. X#include <sys/stat.h>
  3685. X#include <netinet/in.h>
  3686. X#include <netdb.h>
  3687. X#include <stdio.h>
  3688. X#include <syslog.h>
  3689. X#include <pwd.h>
  3690. X#include <grp.h>
  3691. X#include <ctype.h>
  3692. X
  3693. Xextern char *strtok();
  3694. Xextern char *strchr();
  3695. Xextern void closelog();
  3696. X
  3697. X/* Local stuff. */
  3698. X
  3699. X#include "log_tcp.h"
  3700. X
  3701. X/* List of functions that implement the options. Add yours here. */
  3702. X
  3703. Xstatic void user_option();        /* execute "user=name" option */
  3704. Xstatic void group_option();        /* execute "group=name" option */
  3705. Xstatic void umask_option();        /* execute "umask=mask" option */
  3706. Xstatic void twist_option();        /* execute "twist=command" option */
  3707. X#ifdef RFC931_OPTION
  3708. Xstatic void rfc931_option();        /* execute "rfc931" option */
  3709. X#endif
  3710. Xstatic void setenv_option();        /* execute "setenv=name value" */
  3711. X
  3712. Xstatic char *chop_string();        /* strip leading and trailing blanks */
  3713. X
  3714. X/* Structure of the options table. */
  3715. X
  3716. Xstruct option {
  3717. X    char   *name;            /* keyword name, case does not matter */
  3718. X    int     need_value;            /* value required or not */
  3719. X    void    (*func) ();            /* function that does the real work */
  3720. X};
  3721. X
  3722. X/* List of known keywords. Add yours here. */
  3723. X
  3724. Xstatic struct option option_table[] = {
  3725. X    "user", 1, user_option,        /* switch user id */
  3726. X    "group", 1, group_option,        /* switch group id */
  3727. X    "umask", 1, umask_option,        /* change umask */
  3728. X    "spawn", 1, shell_cmd,        /* spawn shell command */
  3729. X    "twist", 1, twist_option,        /* replace current process */
  3730. X#ifdef RFC931_OPTION
  3731. X    "rfc931", 0, rfc931_option,        /* do RFC 931 lookup */
  3732. X#endif
  3733. X    "setenv", 1, setenv_option,        /* update environment */
  3734. X    0,
  3735. X};
  3736. X
  3737. Xstatic char whitespace[] = " \t\r\n";
  3738. X
  3739. X/* process_options - process optional access control information */
  3740. X
  3741. Xprocess_options(options, daemon, client)
  3742. Xchar   *options;
  3743. Xchar   *daemon;
  3744. Xstruct from_host *client;
  3745. X{
  3746. X    char   *key;
  3747. X    char   *value;
  3748. X    struct option *op;
  3749. X
  3750. X    /*
  3751. X     * Light-weight parser. Remember, we may be running as root so we need
  3752. X     * code that is easy to comprehend.
  3753. X     */
  3754. X
  3755. X    for (key = strtok(options, ":"); key; key = strtok((char *) 0, ":")) {
  3756. X    if (value = strchr(key, '=')) {        /* keyword=value */
  3757. X        *value++ = 0;
  3758. X        value = chop_string(value);        /* strip blanks around value */
  3759. X        if (*value == 0)
  3760. X        value = 0;            /* no value left */
  3761. X    }
  3762. X    key = chop_string(key);            /* strip blanks around key */
  3763. X    for (op = option_table; op->name; op++)    /* find keyword */
  3764. X        if (strcasecmp(op->name, key) == 0)
  3765. X        break;
  3766. X    if (op->name == 0) {
  3767. X        syslog(LOG_ERR, "bad option or syntax: \"%s\"", key);
  3768. X    } else if (value == 0 && op->need_value) {
  3769. X        syslog(LOG_ERR, "option \"%s\" requires value", key);
  3770. X    } else if (value && op->need_value == 0) {
  3771. X        syslog(LOG_ERR, "option \"%s\" requires no value", key);
  3772. X    } else {
  3773. X        (*(op->func)) (value, daemon, client);
  3774. X    }
  3775. X    }
  3776. X}
  3777. X
  3778. X/* user_option - switch user id */
  3779. X
  3780. X/* ARGSUSED */
  3781. X
  3782. Xstatic void user_option(value, daemon, client)
  3783. Xchar   *value;
  3784. Xchar   *daemon;
  3785. Xstruct from_host *client;
  3786. X{
  3787. X    struct passwd *pwd;
  3788. X    struct passwd *getpwnam();
  3789. X
  3790. X    if ((pwd = getpwnam(value)) == 0) {
  3791. X    syslog(LOG_ERR, "unknown user: \"%s\"", value);
  3792. X    clean_exit(client);
  3793. X    } else if (setuid(pwd->pw_uid)) {
  3794. X    syslog(LOG_ERR, "setuid(%s): %m", value);
  3795. X    clean_exit(client);
  3796. X    }
  3797. X}
  3798. X
  3799. X/* group_option - switch group id */
  3800. X
  3801. X/* ARGSUSED */
  3802. X
  3803. Xstatic void group_option(value, daemon, client)
  3804. Xchar   *value;
  3805. Xchar   *daemon;
  3806. Xstruct from_host *client;
  3807. X{
  3808. X    struct group *grp;
  3809. X    struct group *getgrnam();
  3810. X
  3811. X    if ((grp = getgrnam(value)) == 0) {
  3812. X    syslog(LOG_ERR, "unknown group: \"%s\"", value);
  3813. X    clean_exit(client);
  3814. X    } else if (setgid(grp->gr_gid)) {
  3815. X    syslog(LOG_ERR, "setgid(%s): %m", value);
  3816. X    clean_exit(client);
  3817. X    }
  3818. X}
  3819. X
  3820. X/* umask_option - set file creation mask */
  3821. X
  3822. X/* ARGSUSED */
  3823. X
  3824. Xstatic void umask_option(value, daemon, client)
  3825. Xchar   *value;
  3826. Xchar   *daemon;
  3827. Xstruct from_host *client;
  3828. X{
  3829. X    unsigned mask;
  3830. X    char    junk;
  3831. X
  3832. X    if (sscanf(value, "%o%c", &mask, &junk) != 1 || (mask & 0777) != mask) {
  3833. X    syslog(LOG_ERR, "bad umask: \"%s\"", value);
  3834. X    clean_exit(client);
  3835. X    }
  3836. X    (void) umask(mask);
  3837. X}
  3838. X
  3839. X/* twist_option - replace process by shell command */
  3840. X
  3841. Xstatic void twist_option(value, daemon, client)
  3842. Xchar   *value;
  3843. Xchar   *daemon;
  3844. Xstruct from_host *client;
  3845. X{
  3846. X    char    buf[BUFSIZ];
  3847. X    int     pid = getpid();
  3848. X    char   *error;
  3849. X
  3850. X    percent_x(buf, sizeof(buf), value, daemon, client, pid);
  3851. X
  3852. X    /* Since we will not be logging in the usual way, do it here and now. */
  3853. X
  3854. X    syslog(SEVERITY, "twist from %s to %s", hosts_info(client), buf);
  3855. X    closelog();
  3856. X
  3857. X    /*
  3858. X     * Before switching to the shell, set up stdout and stderr in case the
  3859. X     * Ultrix inetd didn't.
  3860. X     */
  3861. X
  3862. X    (void) close(1);
  3863. X    (void) close(2);
  3864. X    if (dup(0) != 1 || dup(0) != 2) {
  3865. X    error = "dup: %m";
  3866. X    } else {
  3867. X    (void) execl("/bin/sh", "sh", "-c", buf, (char *) 0);
  3868. X    error = "/bin/sh: %m";
  3869. X    }
  3870. X
  3871. X    /* Can get here only in case of errors. */
  3872. X
  3873. X#ifdef LOG_MAIL
  3874. X    (void) openlog(daemon, LOG_PID, FACILITY);
  3875. X#else
  3876. X    (void) openlog(daemon, LOG_PID);
  3877. X#endif
  3878. X    syslog(LOG_ERR, error);
  3879. X    clean_exit(client);
  3880. X}
  3881. X
  3882. X#ifdef RFC931_OPTION
  3883. X
  3884. X/* rfc931_option - look up remote user name */
  3885. X
  3886. X/* ARGSUSED */
  3887. X
  3888. Xstatic void rfc931_option(value, daemon, client)
  3889. Xchar   *value;
  3890. Xchar   *daemon;
  3891. Xstruct from_host *client;
  3892. X{
  3893. X    if (client->sock_type == FROM_CONNECTED) {
  3894. X    if (client->sin == 0) {
  3895. X        syslog(LOG_ERR, "no socket info for username lookup");
  3896. X    } else {
  3897. X        client->user = rfc931_name(client->sin);
  3898. X    }
  3899. X    }
  3900. X}
  3901. X
  3902. X#endif
  3903. X
  3904. X/* setenv_option - set environment variable */
  3905. X
  3906. X/* ARGSUSED */
  3907. X
  3908. Xstatic void setenv_option(value, daemon, client)
  3909. Xchar   *value;
  3910. Xchar   *daemon;
  3911. Xstruct from_host *client;
  3912. X{
  3913. X    char   *var_name;
  3914. X    char   *var_value;
  3915. X    char    buf[BUFSIZ];
  3916. X    int     pid;
  3917. X
  3918. X    /*
  3919. X     * What we get is one string with the name and the value separated by
  3920. X     * whitespace. Find the end of the name. If that is also the end of the
  3921. X     * string, the value is empty.
  3922. X     */
  3923. X
  3924. X    var_value = value + strcspn(value, whitespace);
  3925. X
  3926. X    if (*var_value == 0) {            /* just a name, that's all */
  3927. X    var_name = value;
  3928. X    } else {                    /* expand %stuff in value */
  3929. X    *var_value++ = 0;
  3930. X    var_name = chop_string(value);
  3931. X    pid = getpid();
  3932. X    percent_x(buf, sizeof(buf), var_value, daemon, client, pid);
  3933. X    var_value = chop_string(buf);
  3934. X    }
  3935. X    if (setenv(var_name, var_value, 1)) {
  3936. X    syslog(LOG_ERR, "memory allocation failure");
  3937. X    clean_exit(client);
  3938. X    }
  3939. X}
  3940. X
  3941. X/* chop_string - strip leading and trailing blanks from string */
  3942. X
  3943. Xstatic char *chop_string(start)
  3944. Xregister char *start;
  3945. X{
  3946. X    register char *end;
  3947. X
  3948. X    while (*start && isspace(*start))
  3949. X    start++;
  3950. X
  3951. X    for (end = start + strlen(start); end > start && isspace(end[-1]); end--)
  3952. X     /* void */ ;
  3953. X    *end = 0;
  3954. X
  3955. X    return (start);
  3956. X}
  3957. END_OF_options.c
  3958. if test 10084 -ne `wc -c <options.c`; then
  3959.     echo shar: \"options.c\" unpacked with wrong size!
  3960. fi
  3961. # end of overwriting check
  3962. fi
  3963. if test -f clean_exit.c -a "${1}" != "-c" ; then 
  3964.   echo shar: Will not over-write existing file \"clean_exit.c\"
  3965. else
  3966. echo shar: Extracting \"clean_exit.c\" \(1268 characters\)
  3967. sed "s/^X//" >clean_exit.c <<'END_OF_clean_exit.c'
  3968. X /*
  3969. X  * clean_exit() cleans up and terminates the program. It should be called
  3970. X  * instead of exit when for some reason the real network daemon will not or
  3971. X  * cannot be run. Reason: in the case of a datagram-oriented service we must
  3972. X  * discard the not-yet received data from the client. Otherwise, inetd will
  3973. X  * see the same datagram again and again, and go into a loop.
  3974. X  * 
  3975. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  3976. X  */
  3977. X
  3978. X#ifndef lint
  3979. Xstatic char sccsid[] = "@(#) clean_exit.c 1.1 92/06/11 22:21:52";
  3980. X#endif
  3981. X
  3982. X#include <sys/types.h>
  3983. X#include <sys/socket.h>
  3984. X#include <stdio.h>
  3985. X
  3986. Xextern void exit();
  3987. X
  3988. X#include "log_tcp.h"
  3989. X
  3990. X/* clean_exit - clean up and exit */
  3991. X
  3992. Xvoid    clean_exit(client)
  3993. Xstruct from_host *client;
  3994. X{
  3995. X    char    buf[BUFSIZ];
  3996. X    struct sockaddr sa;
  3997. X    int     size = sizeof(sa);
  3998. X
  3999. X    /*
  4000. X     * Eat up the not-yet received packet. Some systems insist on a non-zero
  4001. X     * source address argument in the recvfrom() call below.
  4002. X     */
  4003. X
  4004. X    if (client->sock_type == FROM_UNCONNECTED)
  4005. X    (void) recvfrom(0, buf, sizeof(buf), 0, &sa, &size);
  4006. X
  4007. X    /*
  4008. X     * Be kind to the inetd. We already reported the problem via the syslogd,
  4009. X     * and there is no need for additional garbage in the logfile.
  4010. X     */
  4011. X
  4012. X    exit(0);
  4013. X}
  4014. END_OF_clean_exit.c
  4015. if test 1268 -ne `wc -c <clean_exit.c`; then
  4016.     echo shar: \"clean_exit.c\" unpacked with wrong size!
  4017. fi
  4018. # end of overwriting check
  4019. fi
  4020. if test -f setenv.c -a "${1}" != "-c" ; then 
  4021.   echo shar: Will not over-write existing file \"setenv.c\"
  4022. else
  4023. echo shar: Extracting \"setenv.c\" \(931 characters\)
  4024. sed "s/^X//" >setenv.c <<'END_OF_setenv.c'
  4025. X /*
  4026. X  * Some systems do not have setenv(). This one is modeled after 4.4 BSD, but
  4027. X  * is implemented in terms of portable primitives only: getenv(), putenv()
  4028. X  * and malloc(). It should therefore be safe to use on every UNIX system.
  4029. X  * 
  4030. X  * If clobber == 0, do not overwrite an existing variable.
  4031. X  * 
  4032. X  * Returns nonzero if memory allocation fails.
  4033. X  * 
  4034. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  4035. X  */
  4036. X
  4037. X#ifndef lint
  4038. Xstatic char sccsid[] = "@(#) setenv.c 1.1 93/03/07 22:47:58";
  4039. X#endif
  4040. X
  4041. X/* setenv - update or insert environment (name,value) pair */
  4042. X
  4043. Xint     setenv(name, value, clobber)
  4044. Xchar   *name;
  4045. Xchar   *value;
  4046. Xint     clobber;
  4047. X{
  4048. X    char   *malloc();
  4049. X    char   *getenv();
  4050. X    char   *cp;
  4051. X
  4052. X    if (clobber == 0 && getenv(name) != 0)
  4053. X    return (0);
  4054. X    if ((cp = malloc(strlen(name) + strlen(value) + 2)) == 0)
  4055. X    return (1);
  4056. X    sprintf(cp, "%s=%s", name, value);
  4057. X    return (putenv(cp));
  4058. X}
  4059. END_OF_setenv.c
  4060. if test 931 -ne `wc -c <setenv.c`; then
  4061.     echo shar: \"setenv.c\" unpacked with wrong size!
  4062. fi
  4063. # end of overwriting check
  4064. fi
  4065. if test -f patchlevel.h -a "${1}" != "-c" ; then 
  4066.   echo shar: Will not over-write existing file \"patchlevel.h\"
  4067. else
  4068. echo shar: Extracting \"patchlevel.h\" \(70 characters\)
  4069. sed "s/^X//" >patchlevel.h <<'END_OF_patchlevel.h'
  4070. X#ifndef lint
  4071. Xstatic char patchlevel[] = "@(#) patchlevel 5.1";
  4072. X#endif
  4073. END_OF_patchlevel.h
  4074. if test 70 -ne `wc -c <patchlevel.h`; then
  4075.     echo shar: \"patchlevel.h\" unpacked with wrong size!
  4076. fi
  4077. # end of overwriting check
  4078. fi
  4079. if test -f strtok.c -a "${1}" != "-c" ; then 
  4080.   echo shar: Will not over-write existing file \"strtok.c\"
  4081. else
  4082. echo shar: Extracting \"strtok.c\" \(2976 characters\)
  4083. sed "s/^X//" >strtok.c <<'END_OF_strtok.c'
  4084. X/*
  4085. X * Copyright (c) 1988 Regents of the University of California.
  4086. X * All rights reserved.
  4087. X *
  4088. X * Redistribution and use in source and binary forms, with or without
  4089. X * modification, are permitted provided that the following conditions
  4090. X * are met:
  4091. X * 1. Redistributions of source code must retain the above copyright
  4092. X *    notice, this list of conditions and the following disclaimer.
  4093. X * 2. Redistributions in binary form must reproduce the above copyright
  4094. X *    notice, this list of conditions and the following disclaimer in the
  4095. X *    documentation and/or other materials provided with the distribution.
  4096. X * 3. All advertising materials mentioning features or use of this software
  4097. X *    must display the following acknowledgement:
  4098. X *    This product includes software developed by the University of
  4099. X *    California, Berkeley and its contributors.
  4100. X * 4. Neither the name of the University nor the names of its contributors
  4101. X *    may be used to endorse or promote products derived from this software
  4102. X *    without specific prior written permission.
  4103. X *
  4104. X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  4105. X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  4106. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  4107. X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  4108. X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  4109. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  4110. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  4111. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  4112. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  4113. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  4114. X * SUCH DAMAGE.
  4115. X */
  4116. X
  4117. X#if defined(LIBC_SCCS) && !defined(lint)
  4118. Xstatic char sccsid[] = "@(#)strtok.c    5.8 (Berkeley) 2/24/91";
  4119. X#endif /* LIBC_SCCS and not lint */
  4120. X
  4121. X#ifdef __STDC__    /* Added for backwards compatibility -- WZV 930122 */
  4122. X#include <stddef.h>
  4123. X#include <string.h>
  4124. X#else
  4125. X#define const
  4126. X#define NULL 0
  4127. X#endif
  4128. X
  4129. Xchar *
  4130. Xstrtok(s, delim)
  4131. X    register char *s;
  4132. X    register const char *delim;
  4133. X{
  4134. X    register char *spanp;
  4135. X    register int c, sc;
  4136. X    char *tok;
  4137. X    static char *last;
  4138. X
  4139. X
  4140. X    if (s == NULL && (s = last) == NULL)
  4141. X        return (NULL);
  4142. X
  4143. X    /*
  4144. X     * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
  4145. X     */
  4146. Xcont:
  4147. X    c = *s++;
  4148. X    for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
  4149. X        if (c == sc)
  4150. X            goto cont;
  4151. X    }
  4152. X
  4153. X    if (c == 0) {        /* no non-delimiter characters */
  4154. X        last = NULL;
  4155. X        return (NULL);
  4156. X    }
  4157. X    tok = s - 1;
  4158. X
  4159. X    /*
  4160. X     * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
  4161. X     * Note that delim must have one NUL; we stop if we see that, too.
  4162. X     */
  4163. X    for (;;) {
  4164. X        c = *s++;
  4165. X        spanp = (char *)delim;
  4166. X        do {
  4167. X            if ((sc = *spanp++) == c) {
  4168. X                if (c == 0)
  4169. X                    s = NULL;
  4170. X                else
  4171. X                    s[-1] = 0;
  4172. X                last = s;
  4173. X                return (tok);
  4174. X            }
  4175. X        } while (sc != 0);
  4176. X    }
  4177. X    /* NOTREACHED */
  4178. X}
  4179. END_OF_strtok.c
  4180. if test 2976 -ne `wc -c <strtok.c`; then
  4181.     echo shar: \"strtok.c\" unpacked with wrong size!
  4182. fi
  4183. # end of overwriting check
  4184. fi
  4185. if test -f fix_options.c -a "${1}" != "-c" ; then 
  4186.   echo shar: Will not over-write existing file \"fix_options.c\"
  4187. else
  4188. echo shar: Extracting \"fix_options.c\" \(1315 characters\)
  4189. sed "s/^X//" >fix_options.c <<'END_OF_fix_options.c'
  4190. X /*
  4191. X  * Routine to disable IP-level socket options. This code was taken from 4.4BSD
  4192. X  * rlogind source, but all mistakes in it are my fault.
  4193. X  *
  4194. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  4195. X  */
  4196. X
  4197. X#ifndef lint
  4198. Xstatic char sccsid[] = "@(#) fix_options.c 1.1 93/03/07 22:48:02";
  4199. X#endif
  4200. X
  4201. X#include <sys/types.h>
  4202. X#include <sys/param.h>
  4203. X#include <netinet/in.h>
  4204. X#include <netdb.h>
  4205. X#include <stdio.h>
  4206. X#include <syslog.h>
  4207. X
  4208. X#include "log_tcp.h"
  4209. X
  4210. X/* fix_options - get rid of IP-level socket options */
  4211. X
  4212. Xfix_options(client)
  4213. Xstruct from_host *client;
  4214. X{
  4215. X#ifdef IP_OPTIONS
  4216. X    unsigned char optbuf[BUFSIZ / 3], *cp;
  4217. X    char    lbuf[BUFSIZ], *lp;
  4218. X    int     optsize = sizeof(optbuf), ipproto;
  4219. X    struct protoent *ip;
  4220. X
  4221. X    if ((ip = getprotobyname("ip")) != 0)
  4222. X    ipproto = ip->p_proto;
  4223. X    else
  4224. X    ipproto = IPPROTO_IP;
  4225. X
  4226. X    if (getsockopt(0, ipproto, IP_OPTIONS, (char *) optbuf, &optsize) == 0
  4227. X    && optsize != 0) {
  4228. X    lp = lbuf;
  4229. X    for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3)
  4230. X        sprintf(lp, " %2.2x", *cp);
  4231. X    syslog(LOG_NOTICE,
  4232. X           "connect from %s with IP options (ignored):%s",
  4233. X           hosts_info(client), lbuf);
  4234. X    if (setsockopt(0, ipproto, IP_OPTIONS, (char *) 0, optsize) != 0) {
  4235. X        syslog(LOG_ERR, "setsockopt IP_OPTIONS NULL: %m");
  4236. X        clean_exit(client);
  4237. X    }
  4238. X    }
  4239. X#endif
  4240. X}
  4241. END_OF_fix_options.c
  4242. if test 1315 -ne `wc -c <fix_options.c`; then
  4243.     echo shar: \"fix_options.c\" unpacked with wrong size!
  4244. fi
  4245. # end of overwriting check
  4246. fi
  4247. if test -f inet_addr_fix -a "${1}" != "-c" ; then 
  4248.   echo shar: Will not over-write existing file \"inet_addr_fix\"
  4249. else
  4250. echo shar: Extracting \"inet_addr_fix\" \(552 characters\)
  4251. sed "s/^X//" >inet_addr_fix <<'END_OF_inet_addr_fix'
  4252. X#ifndef lint
  4253. Xstatic char sccsid[] = "@(#) inet_addr_fix 1.1 93/03/07 22:48:04";
  4254. X#endif
  4255. X
  4256. X /*
  4257. X  * Some inet_addr() versions return a struct/union instead of a long. You
  4258. X  * have this problem when the compiler complains about illegal lvalues or
  4259. X  * something like that. The following code fixes this mutant behaviour.
  4260. X  * 
  4261. X  * Bug reported by ben@piglet.cr.usgs.gov (Rev. Ben A. Mesander).
  4262. X  */
  4263. X
  4264. Xstatic long fix_inet_addr(string)
  4265. Xchar   *string;
  4266. X{
  4267. X    struct in_addr addr = inet_addr(string);
  4268. X
  4269. X    return (addr.s_addr);
  4270. X}
  4271. X
  4272. X#define inet_addr fix_inet_addr
  4273. END_OF_inet_addr_fix
  4274. if test 552 -ne `wc -c <inet_addr_fix`; then
  4275.     echo shar: \"inet_addr_fix\" unpacked with wrong size!
  4276. fi
  4277. # end of overwriting check
  4278. fi
  4279. echo shar: End of shell archive.
  4280. exit 0
  4281.  
  4282.